mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +08:00 
			
		
		
		
	URL跳转中增加域名跳转、端口跳转
This commit is contained in:
		@@ -6,9 +6,9 @@ import (
 | 
				
			|||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
				
			||||||
	"github.com/iwind/TeaGo/actions"
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
	"github.com/iwind/TeaGo/maps"
 | 
					 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CreatePopupAction struct {
 | 
					type CreatePopupAction struct {
 | 
				
			||||||
@@ -27,6 +27,9 @@ func (this *CreatePopupAction) RunGet(params struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *CreatePopupAction) RunPost(params struct {
 | 
					func (this *CreatePopupAction) RunPost(params struct {
 | 
				
			||||||
 | 
						Type string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// URL
 | 
				
			||||||
	Mode           string
 | 
						Mode           string
 | 
				
			||||||
	BeforeURL      string
 | 
						BeforeURL      string
 | 
				
			||||||
	AfterURL       string
 | 
						AfterURL       string
 | 
				
			||||||
@@ -34,51 +37,129 @@ func (this *CreatePopupAction) RunPost(params struct {
 | 
				
			|||||||
	MatchRegexp    bool
 | 
						MatchRegexp    bool
 | 
				
			||||||
	KeepRequestURI bool
 | 
						KeepRequestURI bool
 | 
				
			||||||
	KeepArgs       bool
 | 
						KeepArgs       bool
 | 
				
			||||||
	Status         int
 | 
					
 | 
				
			||||||
	CondsJSON      []byte
 | 
						// 域名
 | 
				
			||||||
	IsOn           bool
 | 
						DomainsAll        bool
 | 
				
			||||||
 | 
						DomainsBeforeJSON []byte
 | 
				
			||||||
 | 
						DomainAfter       string
 | 
				
			||||||
 | 
						DomainAfterScheme string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 端口
 | 
				
			||||||
 | 
						PortsAll        bool
 | 
				
			||||||
 | 
						PortsBefore     []string
 | 
				
			||||||
 | 
						PortAfter       int
 | 
				
			||||||
 | 
						PortAfterScheme string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Status    int
 | 
				
			||||||
 | 
						CondsJSON []byte
 | 
				
			||||||
 | 
						IsOn      bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Must *actions.Must
 | 
						Must *actions.Must
 | 
				
			||||||
	CSRF *actionutils.CSRF
 | 
						CSRF *actionutils.CSRF
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
	params.Must.
 | 
						var config = &serverconfigs.HTTPHostRedirectConfig{}
 | 
				
			||||||
		Field("beforeURL", params.BeforeURL).
 | 
						config.Type = params.Type
 | 
				
			||||||
		Require("请填写跳转前的URL")
 | 
						config.Status = params.Status
 | 
				
			||||||
 | 
						config.IsOn = params.IsOn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch params.Type {
 | 
				
			||||||
 | 
						case serverconfigs.HTTPHostRedirectTypeURL:
 | 
				
			||||||
 | 
							params.Must.
 | 
				
			||||||
 | 
								Field("beforeURL", params.BeforeURL).
 | 
				
			||||||
 | 
								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)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									this.FailField("beforeURL", "请输入正确的跳转前URL")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (u.Scheme != "http" && u.Scheme != "https") ||
 | 
				
			||||||
 | 
									len(u.Host) == 0 {
 | 
				
			||||||
 | 
									this.FailField("beforeURL", "请输入正确的跳转前URL")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 校验格式
 | 
					 | 
				
			||||||
	if params.MatchRegexp {
 | 
					 | 
				
			||||||
		_, err := regexp.Compile(params.BeforeURL)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			this.Fail("跳转前URL正则表达式错误:" + err.Error())
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		u, err := url.Parse(params.BeforeURL)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			this.FailField("beforeURL", "请输入正确的跳转前URL")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (u.Scheme != "http" && u.Scheme != "https") ||
 | 
					 | 
				
			||||||
			len(u.Host) == 0 {
 | 
					 | 
				
			||||||
			this.FailField("beforeURL", "请输入正确的跳转前URL")
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
							params.Must.
 | 
				
			||||||
 | 
								Field("afterURL", params.AfterURL).
 | 
				
			||||||
 | 
								Require("请填写跳转后URL")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	params.Must.
 | 
							// 校验格式
 | 
				
			||||||
		Field("afterURL", params.AfterURL).
 | 
							if params.MatchRegexp {
 | 
				
			||||||
		Require("请填写跳转后URL")
 | 
								// 正则表达式情况下不做校验
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								u, err := url.Parse(params.AfterURL)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									this.FailField("afterURL", "请输入正确的跳转后URL")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (u.Scheme != "http" && u.Scheme != "https") ||
 | 
				
			||||||
 | 
									len(u.Host) == 0 {
 | 
				
			||||||
 | 
									this.FailField("afterURL", "请输入正确的跳转后URL")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 校验格式
 | 
							config.Mode = params.Mode
 | 
				
			||||||
	if params.MatchRegexp {
 | 
							config.BeforeURL = params.BeforeURL
 | 
				
			||||||
		// 正则表达式情况下不做校验
 | 
							config.AfterURL = params.AfterURL
 | 
				
			||||||
	} else {
 | 
							config.MatchPrefix = params.MatchPrefix
 | 
				
			||||||
		u, err := url.Parse(params.AfterURL)
 | 
							config.MatchRegexp = params.MatchRegexp
 | 
				
			||||||
		if err != nil {
 | 
							config.KeepRequestURI = params.KeepRequestURI
 | 
				
			||||||
			this.FailField("afterURL", "请输入正确的跳转后URL")
 | 
							config.KeepArgs = params.KeepArgs
 | 
				
			||||||
 | 
						case serverconfigs.HTTPHostRedirectTypeDomain:
 | 
				
			||||||
 | 
							config.DomainsAll = params.DomainsAll
 | 
				
			||||||
 | 
							var domainsBefore = []string{}
 | 
				
			||||||
 | 
							if len(params.DomainsBeforeJSON) > 0 {
 | 
				
			||||||
 | 
								err := json.Unmarshal(params.DomainsBeforeJSON, &domainsBefore)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									this.Fail("错误的域名格式:" + err.Error())
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (u.Scheme != "http" && u.Scheme != "https") ||
 | 
							config.DomainsBefore = domainsBefore
 | 
				
			||||||
			len(u.Host) == 0 {
 | 
							if !params.DomainsAll {
 | 
				
			||||||
			this.FailField("afterURL", "请输入正确的跳转后URL")
 | 
								if len(domainsBefore) == 0 {
 | 
				
			||||||
 | 
									this.Fail("请输入跳转前域名")
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if len(params.DomainAfter) == 0 {
 | 
				
			||||||
 | 
								this.FailField("domainAfter", "请输入跳转后域名")
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							config.DomainAfter = params.DomainAfter
 | 
				
			||||||
 | 
							config.DomainAfterScheme = params.DomainAfterScheme
 | 
				
			||||||
 | 
						case serverconfigs.HTTPHostRedirectTypePort:
 | 
				
			||||||
 | 
							config.PortsAll = params.PortsAll
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							config.PortsBefore = params.PortsBefore
 | 
				
			||||||
 | 
							var portReg = regexp.MustCompile(`^\d+$`)
 | 
				
			||||||
 | 
							var portRangeReg = regexp.MustCompile(`^\d+-\d+$`)
 | 
				
			||||||
 | 
							if !config.PortsAll {
 | 
				
			||||||
 | 
								for _, port := range params.PortsBefore {
 | 
				
			||||||
 | 
									port = strings.ReplaceAll(port, " ", "")
 | 
				
			||||||
 | 
									if !portReg.MatchString(port) && !portRangeReg.MatchString(port) {
 | 
				
			||||||
 | 
										this.Fail("端口号" + port + "填写错误(请输入单个端口号或一个端口范围)")
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if len(params.PortsBefore) == 0 {
 | 
				
			||||||
 | 
									this.Fail("请输入跳转前端口")
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if params.PortAfter <= 0 {
 | 
				
			||||||
 | 
								this.FailField("portAfter", "请输入跳转后端口")
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							config.PortAfter = params.PortAfter
 | 
				
			||||||
 | 
							config.PortAfterScheme = params.PortAfterScheme
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	params.Must.
 | 
						params.Must.
 | 
				
			||||||
@@ -99,19 +180,16 @@ func (this *CreatePopupAction) RunPost(params struct {
 | 
				
			|||||||
			this.Fail("匹配条件校验失败:" + err.Error())
 | 
								this.Fail("匹配条件校验失败:" + err.Error())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						config.Conds = conds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.Data["redirect"] = maps.Map{
 | 
						// 校验配置
 | 
				
			||||||
		"mode":           params.Mode,
 | 
						err := config.Init()
 | 
				
			||||||
		"status":         params.Status,
 | 
						if err != nil {
 | 
				
			||||||
		"beforeURL":      params.BeforeURL,
 | 
							this.Fail("配置校验失败:" + err.Error())
 | 
				
			||||||
		"afterURL":       params.AfterURL,
 | 
							return
 | 
				
			||||||
		"matchPrefix":    params.MatchPrefix,
 | 
					 | 
				
			||||||
		"matchRegexp":    params.MatchRegexp,
 | 
					 | 
				
			||||||
		"keepRequestURI": params.KeepRequestURI,
 | 
					 | 
				
			||||||
		"keepArgs":       params.KeepArgs,
 | 
					 | 
				
			||||||
		"conds":          conds,
 | 
					 | 
				
			||||||
		"isOn":           params.IsOn,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Data["redirect"] = config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.Success()
 | 
						this.Success()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -100,10 +100,9 @@ Vue.component("http-host-redirect-box", {
 | 
				
			|||||||
			<thead>
 | 
								<thead>
 | 
				
			||||||
				<tr>
 | 
									<tr>
 | 
				
			||||||
					<th style="width: 1em"></th>
 | 
										<th style="width: 1em"></th>
 | 
				
			||||||
					<th>跳转前URL</th>
 | 
										<th>跳转前</th>
 | 
				
			||||||
					<th style="width: 1em"></th>
 | 
										<th style="width: 1em"></th>
 | 
				
			||||||
					<th>跳转后URL</th>
 | 
										<th>跳转后</th>
 | 
				
			||||||
					<th>匹配模式</th>
 | 
					 | 
				
			||||||
					<th>HTTP状态码</th>
 | 
										<th>HTTP状态码</th>
 | 
				
			||||||
					<th class="two wide">状态</th>
 | 
										<th class="two wide">状态</th>
 | 
				
			||||||
					<th class="two op">操作</th>
 | 
										<th class="two op">操作</th>
 | 
				
			||||||
@@ -113,17 +112,47 @@ Vue.component("http-host-redirect-box", {
 | 
				
			|||||||
				<tr>
 | 
									<tr>
 | 
				
			||||||
					<td style="text-align: center;"><i class="icon bars handle grey"></i> </td>
 | 
										<td style="text-align: center;"><i class="icon bars handle grey"></i> </td>
 | 
				
			||||||
					<td>
 | 
										<td>
 | 
				
			||||||
						{{redirect.beforeURL}}
 | 
											<div v-if="redirect.type == '' || redirect.type == 'url'">
 | 
				
			||||||
 | 
												{{redirect.beforeURL}}
 | 
				
			||||||
 | 
												<div style="margin-top: 0.4em">
 | 
				
			||||||
 | 
													<grey-label><strong>URL跳转</strong></grey-label>
 | 
				
			||||||
 | 
													<grey-label v-if="redirect.matchPrefix">匹配前缀</grey-label>
 | 
				
			||||||
 | 
													<grey-label v-if="redirect.matchRegexp">正则匹配</grey-label>
 | 
				
			||||||
 | 
													<grey-label v-if="!redirect.matchPrefix && !redirect.matchRegexp">精准匹配</grey-label>
 | 
				
			||||||
 | 
												</div>
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
											<div v-if="redirect.type == 'domain'">
 | 
				
			||||||
 | 
												<span v-if="redirect.domainsAll">所有域名</span>
 | 
				
			||||||
 | 
												<span v-if="!redirect.domainsAll && redirect.domainsBefore != null">
 | 
				
			||||||
 | 
													<span v-if="redirect.domainsBefore.length == 1">{{redirect.domainsBefore[0]}}</span>
 | 
				
			||||||
 | 
													<span v-if="redirect.domainsBefore.length > 1">{{redirect.domainsBefore[0]}}等{{redirect.domainsBefore.length}}个域名</span>
 | 
				
			||||||
 | 
												</span>
 | 
				
			||||||
 | 
												<div style="margin-top: 0.4em">
 | 
				
			||||||
 | 
													<grey-label><strong>域名跳转</strong></grey-label>
 | 
				
			||||||
 | 
													<grey-label v-if="redirect.domainAfterScheme != null && redirect.domainAfterScheme.length > 0">{{redirect.domainAfterScheme}}</grey-label>
 | 
				
			||||||
 | 
												</div>
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
											<div v-if="redirect.type == 'port'">
 | 
				
			||||||
 | 
												<span v-if="redirect.portsAll">所有端口</span>
 | 
				
			||||||
 | 
												<span v-if="!redirect.portsAll && redirect.portsBefore != null">
 | 
				
			||||||
 | 
													<span v-if="redirect.portsBefore.length <= 5">{{redirect.portsBefore.join(", ")}}</span>
 | 
				
			||||||
 | 
													<span v-if="redirect.portsBefore.length > 5">{{redirect.portsBefore.slice(0, 5).join(", ")}}等{{redirect.portsBefore.length}}个端口</span>
 | 
				
			||||||
 | 
												</span>
 | 
				
			||||||
 | 
												<div style="margin-top: 0.4em">
 | 
				
			||||||
 | 
													<grey-label><strong>端口跳转</strong></grey-label>
 | 
				
			||||||
 | 
													<grey-label v-if="redirect.portAfterScheme != null && redirect.portAfterScheme.length > 0">{{redirect.portAfterScheme}}</grey-label>
 | 
				
			||||||
 | 
												</div>
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
											
 | 
				
			||||||
						<div style="margin-top: 0.5em" v-if="redirect.conds != null && redirect.conds.groups != null && redirect.conds.groups.length > 0">
 | 
											<div style="margin-top: 0.5em" v-if="redirect.conds != null && redirect.conds.groups != null && redirect.conds.groups.length > 0">
 | 
				
			||||||
							<span class="ui label text basic tiny">匹配条件</span>
 | 
												<grey-label>匹配条件</grey-label>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</td>
 | 
										</td>
 | 
				
			||||||
					<td nowrap="">-></td>
 | 
										<td nowrap="">-></td>
 | 
				
			||||||
					<td>{{redirect.afterURL}}</td>
 | 
					 | 
				
			||||||
					<td>
 | 
										<td>
 | 
				
			||||||
						<span v-if="redirect.matchPrefix">匹配前缀</span>
 | 
											<span v-if="redirect.type == '' || redirect.type == 'url'">{{redirect.afterURL}}</span>
 | 
				
			||||||
						<span v-if="redirect.matchRegexp">正则匹配</span>
 | 
											<span v-if="redirect.type == 'domain'">{{redirect.domainAfter}}</span>
 | 
				
			||||||
						<span v-if="!redirect.matchPrefix && !redirect.matchRegexp">精准匹配</span>
 | 
											<span v-if="redirect.type == 'port'">{{redirect.portAfter}}</span>
 | 
				
			||||||
					</td>
 | 
										</td>
 | 
				
			||||||
					<td>
 | 
										<td>
 | 
				
			||||||
						<span v-if="redirect.status > 0">{{redirect.status}}</span>
 | 
											<span v-if="redirect.status > 0">{{redirect.status}}</span>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,46 +10,129 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <table class="ui table definition selectable">
 | 
					    <table class="ui table definition selectable">
 | 
				
			||||||
        <tr>
 | 
					        <tr>
 | 
				
			||||||
            <td class="title">跳转前URL *</td>
 | 
					            <td class="title">跳转类型</td>
 | 
				
			||||||
            <td>
 | 
					            <td>
 | 
				
			||||||
                <input type="text" name="beforeURL" placeholder="比如 http://www.url1.com" v-model="redirect.beforeURL" ref="focus"/>
 | 
					                <select class="ui dropdown auto-width" name="type" v-model="redirect.type">
 | 
				
			||||||
                <p class="comment">需要填写完整的URL,包括<code-label>http://</code-label>或者<code-label>https://</code-label>,如果有非默认端口,也需要带上端口号。</p>
 | 
					                    <option value="url">URL跳转</option>
 | 
				
			||||||
            </td>
 | 
					                    <option value="domain">域名跳转</option>
 | 
				
			||||||
        </tr>
 | 
					                    <option value="port">端口跳转</option>
 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
            <td>匹配模式 *</td>
 | 
					 | 
				
			||||||
            <td>
 | 
					 | 
				
			||||||
                <select class="ui dropdown auto-width" name="mode" v-model="mode">
 | 
					 | 
				
			||||||
                    <option value="equal">精准匹配</option>
 | 
					 | 
				
			||||||
                    <option value="matchPrefix">匹配前缀</option>
 | 
					 | 
				
			||||||
                    <option value="matchRegexp">正则匹配</option>
 | 
					 | 
				
			||||||
                </select>
 | 
					                </select>
 | 
				
			||||||
                <p class="comment" v-if="mode == 'equal'">精准匹配跳转前的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>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr>
 | 
					 | 
				
			||||||
            <td>跳转后URL *</td>
 | 
					 | 
				
			||||||
            <td>
 | 
					 | 
				
			||||||
                <input type="text" name="afterURL" placeholder="比如 https://www.url2.cn" v-model="redirect.afterURL"/>
 | 
					 | 
				
			||||||
                <p class="comment">需要填写完整的URL,包括<code-label>http://</code-label>或者<code-label>https://</code-label>,如果有非默认端口,也需要带上端口号。</p>
 | 
					 | 
				
			||||||
            </td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr v-if="mode == 'matchPrefix'">
 | 
					 | 
				
			||||||
            <td>是否保留URL路径参数</td>
 | 
					 | 
				
			||||||
            <td>
 | 
					 | 
				
			||||||
                <checkbox name="keepRequestURI" value="1" v-model="redirect.keepRequestURI"></checkbox>
 | 
					 | 
				
			||||||
                <p class="comment">选中后,则跳转之后,保留跳转之前的URL路径和参数。</p>
 | 
					 | 
				
			||||||
            </td>
 | 
					 | 
				
			||||||
        </tr>
 | 
					 | 
				
			||||||
        <tr v-if="mode == 'equal' || mode == 'matchRegexp'">
 | 
					 | 
				
			||||||
            <td>是否保留请求参数</td>
 | 
					 | 
				
			||||||
            <td>
 | 
					 | 
				
			||||||
                <checkbox name="keepArgs" value="1" v-model="redirect.keepArgs"></checkbox>
 | 
					 | 
				
			||||||
                <p class="comment">选中后,则跳转之后,保留跳转之前的URL上的参数(即问号之后的部分)。</p>
 | 
					 | 
				
			||||||
            </td>
 | 
					            </td>
 | 
				
			||||||
        </tr>
 | 
					        </tr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- URL跳转 -->
 | 
				
			||||||
 | 
					        <tbody v-show="redirect.type == 'url'">
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td class="color-border">跳转前URL *</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <input type="text" name="beforeURL" placeholder="比如 http://www.url1.com" v-model="redirect.beforeURL" ref="focus"/>
 | 
				
			||||||
 | 
					                    <p class="comment">需要填写完整的URL,包括<code-label>http://</code-label>或者<code-label>https://</code-label>,如果有非默认端口,也需要带上端口号。</p>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td class="color-border">匹配模式 *</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <select class="ui dropdown auto-width" name="mode" v-model="mode">
 | 
				
			||||||
 | 
					                        <option value="equal">精准匹配</option>
 | 
				
			||||||
 | 
					                        <option value="matchPrefix">匹配前缀</option>
 | 
				
			||||||
 | 
					                        <option value="matchRegexp">正则匹配</option>
 | 
				
			||||||
 | 
					                    </select>
 | 
				
			||||||
 | 
					                    <p class="comment" v-if="mode == 'equal'">精准匹配跳转前的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>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td class="color-border">跳转后URL *</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <input type="text" name="afterURL" placeholder="比如 https://www.url2.cn" v-model="redirect.afterURL"/>
 | 
				
			||||||
 | 
					                    <p class="comment">需要填写完整的URL,包括<code-label>http://</code-label>或者<code-label>https://</code-label>,如果有非默认端口,也需要带上端口号。</p>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr v-if="mode == 'matchPrefix'">
 | 
				
			||||||
 | 
					                <td class="color-border">是否保留URL路径参数</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <checkbox name="keepRequestURI" value="1" v-model="redirect.keepRequestURI"></checkbox>
 | 
				
			||||||
 | 
					                    <p class="comment">选中后,则跳转之后,保留跳转之前的URL路径和参数。</p>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr v-if="mode == 'equal' || mode == 'matchRegexp'">
 | 
				
			||||||
 | 
					                <td class="color-border">是否保留请求参数</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <checkbox name="keepArgs" value="1" v-model="redirect.keepArgs"></checkbox>
 | 
				
			||||||
 | 
					                    <p class="comment">选中后,则跳转之后,保留跳转之前的URL上的参数(即问号之后的部分)。</p>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- 域名跳转 -->
 | 
				
			||||||
 | 
					        <tbody v-show="redirect.type == 'domain'">
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td class="color-border">所有域名都跳转</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <checkbox name="domainsAll" v-model="redirect.domainsAll"></checkbox>
 | 
				
			||||||
 | 
					                    <p class="comment">选中后,表示所有域名都会跳转(只要跳转前后域名不同);不选中后可以指定域名跳转。</p>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr v-show="!redirect.domainsAll">
 | 
				
			||||||
 | 
					                <td class="color-border">指定跳转前域名</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <domains-box name="domainsBeforeJSON" :v-domains="redirect.domainsBefore"></domains-box>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td class="color-border">跳转后域名 *</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <input type="text" name="domainAfter" maxlength="100" v-model="redirect.domainAfter"/>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td class="color-border">跳转后协议</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <select class="ui dropdown auto-width" name="domainAfterScheme" v-model="redirect.domainAfterScheme">
 | 
				
			||||||
 | 
					                        <option value="">保持</option>
 | 
				
			||||||
 | 
					                        <option value="https">HTTPS</option>
 | 
				
			||||||
 | 
					                        <option value="http">HTTP</option>
 | 
				
			||||||
 | 
					                    </select>
 | 
				
			||||||
 | 
					                    <p class="comment">跳转后的URL的协议。</p>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <!-- 端口跳转 -->
 | 
				
			||||||
 | 
					        <tbody v-show="redirect.type == 'port'">
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td class="color-border">所有端口都跳转</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <checkbox name="portsAll" v-model="redirect.portsAll"></checkbox>
 | 
				
			||||||
 | 
					                    <p class="comment">选中后,表示所有端口都会跳转(只要跳转前后端口不同);不选中后可以指定端口跳转。</p>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr v-show="!redirect.portsAll">
 | 
				
			||||||
 | 
					                <td class="color-border">指定跳转前端口</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <values-box placeholder="单个端口 或 端口1-端口2" name="portsBefore" :v-values="redirect.portsBefore"></values-box>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td class="color-border">跳转后端口 *</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <input type="text" name="portAfter" maxlength="5" v-model="redirect.portAfter" style="width: 5em"/>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <td class="color-border">跳转后协议</td>
 | 
				
			||||||
 | 
					                <td>
 | 
				
			||||||
 | 
					                    <select class="ui dropdown auto-width" name="portAfterScheme" v-model="redirect.portAfterScheme">
 | 
				
			||||||
 | 
					                        <option value="">保持</option>
 | 
				
			||||||
 | 
					                        <option value="https">HTTPS</option>
 | 
				
			||||||
 | 
					                        <option value="http">HTTP</option>
 | 
				
			||||||
 | 
					                    </select>
 | 
				
			||||||
 | 
					                    <p class="comment">跳转后的URL的协议。</p>
 | 
				
			||||||
 | 
					                </td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <tr>
 | 
					        <tr>
 | 
				
			||||||
            <td>跳转状态码</td>
 | 
					            <td>跳转状态码</td>
 | 
				
			||||||
            <td>
 | 
					            <td>
 | 
				
			||||||
@@ -64,7 +147,7 @@
 | 
				
			|||||||
            <td><http-request-conds-box :v-conds="redirect.conds" @change="changeConds"></http-request-conds-box></td>
 | 
					            <td><http-request-conds-box :v-conds="redirect.conds" @change="changeConds"></http-request-conds-box></td>
 | 
				
			||||||
        </tr>
 | 
					        </tr>
 | 
				
			||||||
        <tr>
 | 
					        <tr>
 | 
				
			||||||
            <td>是否启用</td>
 | 
					            <td>启用当前跳转</td>
 | 
				
			||||||
            <td><checkbox name="isOn" value="1" v-model="redirect.isOn"></checkbox></td>
 | 
					            <td><checkbox name="isOn" value="1" v-model="redirect.isOn"></checkbox></td>
 | 
				
			||||||
        </tr>
 | 
					        </tr>
 | 
				
			||||||
    </table>
 | 
					    </table>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,8 +3,12 @@ Tea.context(function () {
 | 
				
			|||||||
	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
 | 
				
			||||||
 | 
							if (this.redirect.type == null || this.redirect.type.length == 0) {
 | 
				
			||||||
 | 
								this.redirect.type = "url"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		this.redirect = {
 | 
							this.redirect = {
 | 
				
			||||||
 | 
								type: "url",
 | 
				
			||||||
			status: 0,
 | 
								status: 0,
 | 
				
			||||||
			beforeURL: "",
 | 
								beforeURL: "",
 | 
				
			||||||
			afterURL: "",
 | 
								afterURL: "",
 | 
				
			||||||
@@ -13,7 +17,17 @@ Tea.context(function () {
 | 
				
			|||||||
			keepRequestURI: false,
 | 
								keepRequestURI: false,
 | 
				
			||||||
			keepArgs: true,
 | 
								keepArgs: true,
 | 
				
			||||||
			conds: null,
 | 
								conds: null,
 | 
				
			||||||
			isOn: true
 | 
								isOn: true,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								domainsAll: false,
 | 
				
			||||||
 | 
								domainBefore: [],
 | 
				
			||||||
 | 
								domainAfter: "",
 | 
				
			||||||
 | 
								domainAfterScheme: "",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								portsAll: false,
 | 
				
			||||||
 | 
								portsBefore: [],
 | 
				
			||||||
 | 
								portAfter: 0,
 | 
				
			||||||
 | 
								portAfterScheme: ""
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user