URL跳转支持正则匹配

This commit is contained in:
GoEdgeLab
2021-05-23 17:01:54 +08:00
parent 163a49003e
commit e0dbd2300e
4 changed files with 64 additions and 23 deletions

View File

@@ -6,6 +6,7 @@ import (
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
"net/url" "net/url"
"regexp"
) )
type CreatePopupAction struct { type CreatePopupAction struct {
@@ -27,6 +28,7 @@ func (this *CreatePopupAction) RunPost(params struct {
BeforeURL string BeforeURL string
AfterURL string AfterURL string
MatchPrefix bool MatchPrefix bool
MatchRegexp bool
KeepRequestURI bool KeepRequestURI bool
Status int Status int
@@ -39,7 +41,12 @@ func (this *CreatePopupAction) RunPost(params struct {
Require("请填写跳转前的URL") Require("请填写跳转前的URL")
// 校验格式 // 校验格式
{ if params.MatchRegexp {
_, err := regexp.Compile(params.BeforeURL)
if err != nil {
this.Fail("跳转前URL正则表达式错误" + err.Error())
}
} else {
u, err := url.Parse(params.BeforeURL) u, err := url.Parse(params.BeforeURL)
if err != nil { if err != nil {
this.FailField("beforeURL", "请输入正确的跳转前URL") this.FailField("beforeURL", "请输入正确的跳转前URL")
@@ -56,7 +63,9 @@ func (this *CreatePopupAction) RunPost(params struct {
Require("请填写跳转后URL") Require("请填写跳转后URL")
// 校验格式 // 校验格式
{ if params.MatchRegexp {
// 正则表达式情况下不做校验
} else {
u, err := url.Parse(params.AfterURL) u, err := url.Parse(params.AfterURL)
if err != nil { if err != nil {
this.FailField("afterURL", "请输入正确的跳转后URL") this.FailField("afterURL", "请输入正确的跳转后URL")
@@ -76,6 +85,7 @@ func (this *CreatePopupAction) RunPost(params struct {
"beforeURL": params.BeforeURL, "beforeURL": params.BeforeURL,
"afterURL": params.AfterURL, "afterURL": params.AfterURL,
"matchPrefix": params.MatchPrefix, "matchPrefix": params.MatchPrefix,
"matchRegexp": params.MatchRegexp,
"keepRequestURI": params.KeepRequestURI, "keepRequestURI": params.KeepRequestURI,
"isOn": true, "isOn": true,
} }

View File

@@ -50,7 +50,10 @@ Vue.component("http-host-redirect-box", {
<!-- TODO 将来支持排序并支持isOn切换 --> <!-- TODO 将来支持排序并支持isOn切换 -->
<div v-if="redirects.length > 0"> <div v-if="redirects.length > 0">
<div v-for="(redirect, index) in redirects" class="ui label basic small" style="margin-bottom: 0.5em;margin-top: 0.5em"> <div v-for="(redirect, index) in redirects" class="ui label basic small" style="margin-bottom: 0.5em;margin-top: 0.5em">
<span v-if="redirect.status > 0">[{{redirect.status}}]</span><span v-if="redirect.matchPrefix">[prefix]</span> {{redirect.beforeURL}} -&gt; {{redirect.afterURL}} <a href="" @click.prevent="update(index, redirect)" title="修改"><i class="icon pencil small"></i></a> &nbsp; <a href="" @click.prevent="remove(index)" title="删除"><i class="icon remove"></i></a> <span v-if="redirect.status > 0" class="small grey">[{{redirect.status}}]</span>
<span v-if="redirect.matchPrefix" class="small grey">[匹配前缀]</span>
<span v-if="redirect.matchRegexp" class="small grey">[正则匹配]</span>
{{redirect.beforeURL}} -&gt; {{redirect.afterURL}} <a href="" @click.prevent="update(index, redirect)" title="修改"><i class="icon pencil small"></i></a> &nbsp; <a href="" @click.prevent="remove(index)" title="删除"><i class="icon remove"></i></a>
</div> </div>
<div class="ui divider"></div> <div class="ui divider"></div>
</div> </div>

View File

@@ -5,6 +5,8 @@
<form class="ui form" data-tea-success="success" data-tea-action="$"> <form class="ui form" data-tea-success="success" data-tea-action="$">
<csrf-token></csrf-token> <csrf-token></csrf-token>
<input type="hidden" name="matchPrefix" :value="redirect.matchPrefix ? 1 : 0"/>
<input type="hidden" name="matchRegexp" :value="redirect.matchRegexp ? 1 : 0"/>
<table class="ui table definition selectable"> <table class="ui table definition selectable">
<tr> <tr>
@@ -17,15 +19,17 @@
<tr> <tr>
<td>匹配模式</td> <td>匹配模式</td>
<td> <td>
<select class="ui dropdown auto-width" name="matchPrefix" v-model="matchPrefix"> <select class="ui dropdown auto-width" name="mode" v-model="mode">
<option value="0">精准匹配</option> <option value="equal">精准匹配</option>
<option value="1">匹配前缀</option> <option value="matchPrefix">匹配前缀</option>
<option value="matchRegexp">正则匹配</option>
</select> </select>
<p class="comment" v-if="matchPrefix == 0">精准匹配跳转前的URL。</p> <p class="comment" v-if="mode == 'equal'">精准匹配跳转前的URL即只有访问完全一样的URL才会跳转</p>
<p class="comment" v-if="matchPrefix == 1">只要URL头部部分包含跳转前URL即可跳转。</p> <p class="comment" v-if="mode == 'matchPrefix'">只要访问的URL头部部分包含跳转前URL即可跳转。</p>
<p class="comment" v-if="mode == 'matchRegexp'">可以在跳转前URL中使用正则表达式然后可以在跳转后URL中使用正则表达式中括号的变量比如<code-label>${1}</code-label><code-label>${2}</code-label>等。</p>
</td> </td>
</tr> </tr>
<tr v-if="matchPrefix == 1"> <tr v-if="mode == 'matchPrefix'">
<td>是否保留URL路径参数</td> <td>是否保留URL路径参数</td>
<td> <td>
<checkbox name="keepRequestURI" value="1" v-model="redirect.keepRequestURI"></checkbox> <checkbox name="keepRequestURI" value="1" v-model="redirect.keepRequestURI"></checkbox>

View File

@@ -1,17 +1,41 @@
Tea.context(function () { Tea.context(function () {
this.isCreating = true this.isCreating = true
if (window.parent.UPDATING_REDIRECT != null) { if (window.parent.UPDATING_REDIRECT != null) {
this.isCreating = false this.isCreating = false
this.redirect = window.parent.UPDATING_REDIRECT this.redirect = window.parent.UPDATING_REDIRECT
} else { } else {
this.redirect = { this.redirect = {
status: 0, status: 0,
beforeURL: "", beforeURL: "",
afterURL: "", afterURL: "",
matchPrefix: false, matchPrefix: false,
keepRequestURI: false matchRegexp: false,
} keepRequestURI: false
} }
}
this.matchPrefix = (this.redirect.matchPrefix ? 1 : 0) this.mode = ""
if (this.redirect.matchPrefix) {
this.mode = "matchPrefix"
} else if (this.redirect.matchRegexp) {
this.mode = "matchRegexp"
} else {
this.mode = "equal"
}
this.$delay(function () {
let that = this
this.$watch("mode", function (v) {
if (v == "matchPrefix") {
that.redirect.matchPrefix = true
that.redirect.matchRegexp = false
} else if (v == "matchRegexp") {
that.redirect.matchPrefix = false
that.redirect.matchRegexp = true
} else {
that.redirect.matchPrefix = false
that.redirect.matchRegexp = false
}
})
})
}) })