mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-06 06:40:27 +08:00
更新components.js
This commit is contained in:
@@ -3177,6 +3177,7 @@ Vue.component("plan-price-bandwidth-config-box", {
|
||||
带宽百分位:<span v-if="config.percentile > 0">{{config.percentile}}th</span><span v-else class="disabled">没有设置</span> |
|
||||
基础带宽价格:<span v-if="config.base > 0">{{config.base}}元/Mbps</span><span v-else class="disabled">没有设置</span> |
|
||||
阶梯价格:<span v-if="config.ranges.length > 0">{{config.ranges.length}}段</span><span v-else class="disabled">没有设置</span> <span v-if="config.supportRegions">| 支持区域带宽计费</span>
|
||||
<span v-if="config.bandwidthAlgo == 'avg'"> | 使用平均带宽算法</span>
|
||||
<div style="margin-top: 0.5em">
|
||||
<a href="" @click.prevent="edit">修改 <i class="icon angle" :class="{up: isEditing, down: !isEditing}"></i></a>
|
||||
</div>
|
||||
@@ -3216,6 +3217,17 @@ Vue.component("plan-price-bandwidth-config-box", {
|
||||
<p class="comment">选中后,表示可以根据节点所在区域设置不同的带宽价格。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>带宽算法</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="config.bandwidthAlgo">
|
||||
<option value="secondly">峰值带宽</option>
|
||||
<option value="avg">平均带宽</option>
|
||||
</select>
|
||||
<p class="comment" v-if="config.bandwidthAlgo == 'secondly'">按在计时时间段内(5分钟)最高带宽峰值计算,比如5分钟内最高的某个时间点带宽为100Mbps,那么就认为此时间段内的峰值带宽为100Mbps。修改此选项会同时影响到用量统计图表。</p>
|
||||
<p class="comment" v-if="config.bandwidthAlgo == 'avg'">按在计时时间段内(5分钟)平均带宽计算,即此时间段内的总流量除以时间段的秒数,比如5分钟(300秒)内总流量600MB,那么带宽即为<code-label>600MB * 8bit/300s = 16Mbps</code-label>;通常平均带宽算法要比峰值带宽要少很多。修改此选项会同时影响到用量统计图表。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>`
|
||||
@@ -4239,7 +4251,7 @@ Vue.component("http-firewall-rule-label", {
|
||||
|
||||
<span v-else>
|
||||
<span v-if="rule.paramFilters != null && rule.paramFilters.length > 0" v-for="paramFilter in rule.paramFilters"> | {{paramFilter.code}}</span>
|
||||
<span :class="{dash:rule.isCaseInsensitive}" :title="rule.isCaseInsensitive ? '大小写不敏感':''" v-if="!rule.isComposed">{{operatorName(rule.operator)}}</span>
|
||||
<span :class="{dash:!rule.isComposed && rule.isCaseInsensitive}" :title="(!rule.isComposed && rule.isCaseInsensitive) ? '大小写不敏感':''">{{operatorName(rule.operator)}}</span>
|
||||
<span v-if="!isEmptyString(rule.value)">{{rule.value}}</span>
|
||||
<span v-else class="disabled" style="font-weight: normal" title="空字符串">[空]</span>
|
||||
</span>
|
||||
@@ -4807,7 +4819,10 @@ Vue.component("http-cache-ref-box", {
|
||||
<tr v-if="condCategory == 'simple'">
|
||||
<td class="color-border">{{condComponent.paramsTitle}} *</td>
|
||||
<td>
|
||||
<component :is="condComponent.component" :v-cond="ref.simpleCond"></component>
|
||||
<component :is="condComponent.component" :v-cond="ref.simpleCond" v-if="condComponent.type != 'params'"></component>
|
||||
<table class="ui table" v-if="condComponent.type == 'params'">
|
||||
<component :is="condComponent.component" :v-cond="ref.simpleCond"></component>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="condCategory == 'simple' && condComponent.caseInsensitive">
|
||||
@@ -5217,39 +5232,57 @@ Vue.component("http-firewall-config-box", {
|
||||
firewall = {
|
||||
isPrior: false,
|
||||
isOn: false,
|
||||
firewallPolicyId: 0
|
||||
firewallPolicyId: 0,
|
||||
ignoreGlobalRules: false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
firewall: firewall
|
||||
firewall: firewall,
|
||||
moreOptionsVisible: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeOptionsVisible: function (v) {
|
||||
this.moreOptionsVisible = v
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" name="firewallJSON" :value="JSON.stringify(firewall)"/>
|
||||
|
||||
<table class="ui table selectable definition" v-show="!vIsGroup">
|
||||
<tr>
|
||||
<td class="title">全局WAF策略</td>
|
||||
<td>
|
||||
<div v-if="vFirewallPolicy != null">{{vFirewallPolicy.name}} <span v-if="vFirewallPolicy.modeInfo != null"> <span :class="{green: vFirewallPolicy.modeInfo.code == 'defend', blue: vFirewallPolicy.modeInfo.code == 'observe', grey: vFirewallPolicy.modeInfo.code == 'bypass'}">[{{vFirewallPolicy.modeInfo.name}}]</span> </span> <link-icon :href="'/servers/components/waf/policy?firewallPolicyId=' + vFirewallPolicy.id"></link-icon>
|
||||
<p class="comment">当前服务所在集群的设置。</p>
|
||||
</div>
|
||||
<span v-else class="red">当前集群没有设置WAF策略,当前配置无法生效。</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table class="ui table selectable definition">
|
||||
<prior-checkbox :v-config="firewall" v-if="vIsLocation || vIsGroup"></prior-checkbox>
|
||||
<tbody v-show="(!vIsLocation && !vIsGroup) || firewall.isPrior">
|
||||
<tr v-show="!vIsGroup">
|
||||
<td>WAF策略</td>
|
||||
<td>
|
||||
<div v-if="vFirewallPolicy != null">{{vFirewallPolicy.name}} <span v-if="vFirewallPolicy.modeInfo != null"> <span :class="{green: vFirewallPolicy.modeInfo.code == 'defend', blue: vFirewallPolicy.modeInfo.code == 'observe', grey: vFirewallPolicy.modeInfo.code == 'bypass'}">[{{vFirewallPolicy.modeInfo.name}}]</span> </span> <link-icon :href="'/servers/components/waf/policy?firewallPolicyId=' + vFirewallPolicy.id"></link-icon>
|
||||
<p class="comment">使用当前服务所在集群的设置。</p>
|
||||
</div>
|
||||
<span v-else class="red">当前集群没有设置WAF策略,当前配置无法生效。</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">启用WAF</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" v-model="firewall.isOn"/>
|
||||
<label></label>
|
||||
</div>
|
||||
<checkbox v-model="firewall.isOn"></checkbox>
|
||||
<p class="comment">启用WAF之后,各项WAF设置才会生效。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<more-options-tbody @change="changeOptionsVisible"></more-options-tbody>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>不使用全局规则</td>
|
||||
<td>
|
||||
<checkbox v-model="firewall.ignoreGlobalRules"></checkbox>
|
||||
<p class="comment">选中后,表示<strong>不使用</strong>系统全局WAF策略中定义的规则。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="margin"></div>
|
||||
</div>`
|
||||
@@ -6352,7 +6385,7 @@ Vue.component("http-cache-refs-config-box", {
|
||||
})
|
||||
},
|
||||
updateRef: function (index, cacheRef) {
|
||||
window.UPDATING_CACHE_REF = cacheRef
|
||||
window.UPDATING_CACHE_REF = teaweb.clone(cacheRef)
|
||||
|
||||
let height = window.innerHeight
|
||||
if (height > 500) {
|
||||
@@ -7137,7 +7170,7 @@ Vue.component("firewall-syn-flood-config-viewer", {
|
||||
},
|
||||
template: `<div>
|
||||
<span v-if="config.isOn">
|
||||
已启用 / <span>空连接次数:{{config.minAttempts}}次/分钟</span> / 封禁时间:{{config.timeoutSeconds}}秒 <span v-if="config.ignoreLocal">/ 忽略局域网访问</span>
|
||||
已启用 / <span>空连接次数:{{config.minAttempts}}次/分钟</span> / 封禁时长:{{config.timeoutSeconds}}秒 <span v-if="config.ignoreLocal">/ 忽略局域网访问</span>
|
||||
</span>
|
||||
<span v-else>未启用</span>
|
||||
</div>`
|
||||
@@ -7411,8 +7444,16 @@ Vue.component("http-referers-config-box", {
|
||||
return ((!this.vIsLocation && !this.vIsGroup) || this.config.isPrior) && this.config.isOn
|
||||
},
|
||||
changeAllowDomains: function (domains) {
|
||||
if (typeof (domains) == "object") {
|
||||
this.config.allowDomains = domains
|
||||
this.$forceUpdate()
|
||||
}
|
||||
},
|
||||
changeDenyDomains: function (domains) {
|
||||
if (typeof (domains) == "object") {
|
||||
this.config.denyDomains = domains
|
||||
this.$forceUpdate()
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
@@ -7702,6 +7743,7 @@ Vue.component("http-firewall-actions-box", {
|
||||
|
||||
// 动作参数
|
||||
blockTimeout: "",
|
||||
blockTimeoutMax: "",
|
||||
blockScope: "global",
|
||||
|
||||
captchaLife: "",
|
||||
@@ -7751,6 +7793,14 @@ Vue.component("http-firewall-actions-box", {
|
||||
this.actionOptions["timeout"] = v
|
||||
}
|
||||
},
|
||||
blockTimeoutMax: function (v) {
|
||||
v = parseInt(v)
|
||||
if (isNaN(v)) {
|
||||
this.actionOptions["timeoutMax"] = 0
|
||||
} else {
|
||||
this.actionOptions["timeoutMax"] = v
|
||||
}
|
||||
},
|
||||
blockScope: function (v) {
|
||||
this.actionOptions["scope"] = v
|
||||
},
|
||||
@@ -7866,6 +7916,7 @@ Vue.component("http-firewall-actions-box", {
|
||||
|
||||
// 动作参数
|
||||
this.blockTimeout = ""
|
||||
this.blockTimeoutMax = ""
|
||||
this.blockScope = "global"
|
||||
|
||||
this.captchaLife = ""
|
||||
@@ -7927,9 +7978,13 @@ Vue.component("http-firewall-actions-box", {
|
||||
switch (config.code) {
|
||||
case "block":
|
||||
this.blockTimeout = ""
|
||||
this.blockTimeoutMax = ""
|
||||
if (config.options.timeout != null || config.options.timeout > 0) {
|
||||
this.blockTimeout = config.options.timeout.toString()
|
||||
}
|
||||
if (config.options.timeoutMax != null || config.options.timeoutMax > 0) {
|
||||
this.blockTimeoutMax = config.options.timeoutMax.toString()
|
||||
}
|
||||
if (config.options.scope != null && config.options.scope.length > 0) {
|
||||
this.blockScope = config.options.scope
|
||||
} else {
|
||||
@@ -8213,7 +8268,7 @@ Vue.component("http-firewall-actions-box", {
|
||||
{{config.name}} <span class="small">({{config.code.toUpperCase()}})</span>
|
||||
|
||||
<!-- block -->
|
||||
<span v-if="config.code == 'block' && config.options.timeout > 0">:有效期{{config.options.timeout}}秒</span>
|
||||
<span v-if="config.code == 'block' && config.options.timeout > 0">:封禁时长{{config.options.timeout}}<span v-if="config.options.timeoutMax > config.options.timeout">-{{config.options.timeoutMax}}</span>秒</span>
|
||||
|
||||
<!-- captcha -->
|
||||
<span v-if="config.code == 'captcha' && config.options.life > 0">:有效期{{config.options.life}}秒
|
||||
@@ -8272,7 +8327,18 @@ Vue.component("http-firewall-actions-box", {
|
||||
|
||||
<!-- block -->
|
||||
<tr v-if="actionCode == 'block'">
|
||||
<td>封锁时间</td>
|
||||
<td>封禁范围</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="blockScope">
|
||||
<option value="service">当前服务</option>
|
||||
<option value="global">所有服务</option>
|
||||
</select>
|
||||
<p class="comment" v-if="blockScope == 'service'">只封禁用户对当前网站服务的访问,其他服务不受影响。</p>
|
||||
<p class="comment" v-if="blockScope =='global'">封禁用户对所有网站服务的访问。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="actionCode == 'block'">
|
||||
<td>封禁时长</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" style="width: 5em" maxlength="9" v-model="blockTimeout" @keyup.enter="confirm()" @keypress.enter.prevent="1"/>
|
||||
@@ -8281,14 +8347,13 @@ Vue.component("http-firewall-actions-box", {
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="actionCode == 'block'">
|
||||
<td>封锁范围</td>
|
||||
<td>最大封禁时长</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="blockScope">
|
||||
<option value="service">当前服务</option>
|
||||
<option value="global">所有服务</option>
|
||||
</select>
|
||||
<p class="comment" v-if="blockScope == 'service'">只封锁用户对当前网站服务的访问,其他服务不受影响。</p>
|
||||
<p class="comment" v-if="blockScope =='global'">封锁用户对所有网站服务的访问。</p>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" style="width: 5em" maxlength="9" v-model="blockTimeoutMax" @keyup.enter="confirm()" @keypress.enter.prevent="1"/>
|
||||
<span class="ui label">秒</span>
|
||||
</div>
|
||||
<p class="comment">选填项。如果同时填写了封禁时长和最大封禁时长,则会在两者之间随机选择一个数字作为最终的封禁时长。</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -10152,7 +10217,7 @@ Vue.component("http-firewall-block-options-viewer", {
|
||||
template: `<div>
|
||||
<span v-if="options == null">默认设置</span>
|
||||
<div v-else>
|
||||
状态码:{{options.statusCode}} / 提示内容:<span v-if="options.body != null && options.body.length > 0">[{{options.body.length}}字符]</span><span v-else class="disabled">[无]</span> / 超时时间:{{options.timeout}}秒
|
||||
状态码:{{options.statusCode}} / 提示内容:<span v-if="options.body != null && options.body.length > 0">[{{options.body.length}}字符]</span><span v-else class="disabled">[无]</span> / 超时时间:{{options.timeout}}秒 <span v-if="options.timeoutMax > options.timeout">/ 最大封禁时长:{{options.timeoutMax}}秒</span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
@@ -11846,6 +11911,7 @@ Vue.component("http-firewall-block-options", {
|
||||
blockOptions: this.vBlockOptions,
|
||||
statusCode: this.vBlockOptions.statusCode,
|
||||
timeout: this.vBlockOptions.timeout,
|
||||
timeoutMax: this.vBlockOptions.timeoutMax,
|
||||
isEditing: false
|
||||
}
|
||||
},
|
||||
@@ -11865,6 +11931,14 @@ Vue.component("http-firewall-block-options", {
|
||||
} else {
|
||||
this.blockOptions.timeout = timeout
|
||||
}
|
||||
},
|
||||
timeoutMax: function (v) {
|
||||
let timeoutMax = parseInt(v)
|
||||
if (isNaN(timeoutMax)) {
|
||||
this.blockOptions.timeoutMax = 0
|
||||
} else {
|
||||
this.blockOptions.timeoutMax = timeoutMax
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -11874,7 +11948,9 @@ Vue.component("http-firewall-block-options", {
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" name="blockOptionsJSON" :value="JSON.stringify(blockOptions)"/>
|
||||
<a href="" @click.prevent="edit">状态码:{{statusCode}} / 提示内容:<span v-if="blockOptions.body != null && blockOptions.body.length > 0">[{{blockOptions.body.length}}字符]</span><span v-else class="disabled">[无]</span> / 超时时间:{{timeout}}秒 <i class="icon angle" :class="{up: isEditing, down: !isEditing}"></i></a>
|
||||
<a href="" @click.prevent="edit">状态码:{{statusCode}} / 提示内容:<span v-if="blockOptions.body != null && blockOptions.body.length > 0">[{{blockOptions.body.length}}字符]</span><span v-else class="disabled">[无]</span> <span v-if="timeout > 0"> / 封禁时长:{{timeout}}秒</span>
|
||||
<span v-if="timeoutMax > timeout"> / 最大封禁时长:{{timeoutMax}}秒</span>
|
||||
<i class="icon angle" :class="{up: isEditing, down: !isEditing}"></i></a>
|
||||
<table class="ui table" v-show="isEditing">
|
||||
<tr>
|
||||
<td class="title">状态码</td>
|
||||
@@ -11889,13 +11965,23 @@ Vue.component("http-firewall-block-options", {
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>超时时间</td>
|
||||
<td>封禁时长</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" v-model="timeout" style="width: 5em" maxlength="6"/>
|
||||
<span class="ui label">秒</span>
|
||||
</div>
|
||||
<p class="comment">触发阻止动作时,封锁客户端IP的时间。</p>
|
||||
<p class="comment">触发阻止动作时,封禁客户端IP的时间。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>最大封禁时长</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" v-model="timeoutMax" style="width: 5em" maxlength="6"/>
|
||||
<span class="ui label">秒</span>
|
||||
</div>
|
||||
<p class="comment">如果最大封禁时长大于封禁时长({{timeout}}秒),那么表示每次封禁的时候,将会在这两个时长数字之间随机选取一个数字作为最终的封禁时长。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -12059,7 +12145,7 @@ Vue.component("http-firewall-rules-box", {
|
||||
</span>
|
||||
|
||||
<span v-else>
|
||||
<span v-if="rule.paramFilters != null && rule.paramFilters.length > 0" v-for="paramFilter in rule.paramFilters"> | {{paramFilter.code}}</span> <span :class="{dash:rule.isCaseInsensitive}" :title="rule.isCaseInsensitive ? '大小写不敏感':''">{{operatorName(rule.operator)}}</span>
|
||||
<span v-if="rule.paramFilters != null && rule.paramFilters.length > 0" v-for="paramFilter in rule.paramFilters"> | {{paramFilter.code}}</span> <span :class="{dash:(!rule.isComposed && rule.isCaseInsensitive)}" :title="(!rule.isComposed && rule.isCaseInsensitive) ? '大小写不敏感':''">{{operatorName(rule.operator)}}</span>
|
||||
<span v-if="!isEmptyString(rule.value)">{{rule.value}}</span>
|
||||
<span v-else class="disabled" style="font-weight: normal" title="空字符串">[空]</span>
|
||||
</span>
|
||||
@@ -12255,7 +12341,7 @@ Vue.component("http-cond-url-extension", {
|
||||
data: function () {
|
||||
let cond = {
|
||||
isRequest: true,
|
||||
param: "${requestPathExtension}",
|
||||
param: "${requestPathLowerExtension}",
|
||||
operator: "in",
|
||||
value: "[]"
|
||||
}
|
||||
@@ -12346,7 +12432,7 @@ Vue.component("http-cond-url-not-extension", {
|
||||
data: function () {
|
||||
let cond = {
|
||||
isRequest: true,
|
||||
param: "${requestPathExtension}",
|
||||
param: "${requestPathLowerExtension}",
|
||||
operator: "not in",
|
||||
value: "[]"
|
||||
}
|
||||
@@ -12969,21 +13055,19 @@ Vue.component("http-cond-params", {
|
||||
},
|
||||
template: `<tbody>
|
||||
<tr>
|
||||
<td>参数值</td>
|
||||
<td style="width: 8em">参数值</td>
|
||||
<td>
|
||||
<input type="hidden" name="condJSON" :value="JSON.stringify(cond)"/>
|
||||
<div>
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field">
|
||||
<input type="text" placeholder="\${xxx}" v-model="cond.param"/>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<select class="ui dropdown" style="width: 7em; color: grey" v-model="variable" @change="changeVariable">
|
||||
<option value="">[常用参数]</option>
|
||||
<option v-for="v in variables" :value="v.code">{{v.code}} - {{v.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<input type="text" placeholder="\${xxx}" v-model="cond.param"/>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<select class="ui dropdown" style="width: 16em; color: grey" v-model="variable" @change="changeVariable">
|
||||
<option value="">[常用参数]</option>
|
||||
<option v-for="v in variables" :value="v.code">{{v.code}} - {{v.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<p class="comment">其中可以使用变量,类似于<code-label>\${requestPath}</code-label>,也可以是多个变量的组合。</p>
|
||||
</td>
|
||||
@@ -13086,7 +13170,8 @@ Vue.component("http-cond-params", {
|
||||
<p class="comment">选中后表示对比时忽略参数值的大小写。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>`
|
||||
</tbody>
|
||||
`
|
||||
})
|
||||
|
||||
// 请求方法列表
|
||||
@@ -13843,7 +13928,7 @@ Vue.component("firewall-syn-flood-config-box", {
|
||||
<input type="hidden" name="synFloodJSON" :value="JSON.stringify(config)"/>
|
||||
<a href="" @click.prevent="edit">
|
||||
<span v-if="config.isOn">
|
||||
已启用 / <span>空连接次数:{{config.minAttempts}}次/分钟</span> / 封禁时间:{{config.timeoutSeconds}}秒 <span v-if="config.ignoreLocal">/ 忽略局域网访问</span>
|
||||
已启用 / <span>空连接次数:{{config.minAttempts}}次/分钟</span> / 封禁时长:{{config.timeoutSeconds}}秒 <span v-if="config.ignoreLocal">/ 忽略局域网访问</span>
|
||||
</span>
|
||||
<span v-else>未启用</span>
|
||||
<i class="icon angle" :class="{up: isEditing, down: !isEditing}"></i>
|
||||
@@ -13868,7 +13953,7 @@ Vue.component("firewall-syn-flood-config-box", {
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>封禁时间</td>
|
||||
<td>封禁时长</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" v-model="timeoutSeconds" style="width: 5em" maxlength="8"/>
|
||||
@@ -14891,7 +14976,7 @@ Vue.component("download-link", {
|
||||
})
|
||||
|
||||
Vue.component("values-box", {
|
||||
props: ["values", "v-values", "size", "maxlength", "name", "placeholder", "v-allow-empty"],
|
||||
props: ["values", "v-values", "size", "maxlength", "name", "placeholder", "v-allow-empty", "validator"],
|
||||
data: function () {
|
||||
let values = this.values;
|
||||
if (values == null) {
|
||||
@@ -14936,6 +15021,22 @@ Vue.component("values-box", {
|
||||
}
|
||||
}
|
||||
|
||||
// validate
|
||||
if (typeof(this.validator) == "function") {
|
||||
let resp = this.validator.call(this, this.value)
|
||||
if (typeof resp == "object") {
|
||||
if (typeof resp.isOk == "boolean" && !resp.isOk) {
|
||||
if (typeof resp.message == "string") {
|
||||
let that = this
|
||||
teaweb.warn(resp.message, function () {
|
||||
that.$refs.value.focus();
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isUpdating) {
|
||||
Vue.set(this.realValues, this.index, this.value);
|
||||
} else {
|
||||
@@ -15251,6 +15352,34 @@ Vue.component("pro-warning-label", {
|
||||
})
|
||||
|
||||
|
||||
Vue.component("js-page", {
|
||||
props: ["v-max"],
|
||||
data: function () {
|
||||
let max = this.vMax
|
||||
if (max == null) {
|
||||
max = 0
|
||||
}
|
||||
return {
|
||||
max: max,
|
||||
page: 1
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateMax: function (max) {
|
||||
this.max = max
|
||||
},
|
||||
selectPage: function(page) {
|
||||
this.page = page
|
||||
this.$emit("change", page)
|
||||
}
|
||||
},
|
||||
template:`<div>
|
||||
<div class="page" v-if="max > 1">
|
||||
<a href="" v-for="i in max" :class="{active: i == page}" @click.prevent="selectPage(i)">{{i}}</a>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
|
||||
/**
|
||||
* 一级菜单
|
||||
*/
|
||||
@@ -17041,6 +17170,60 @@ Vue.component("node-cache-disk-dirs-box", {
|
||||
</div>`
|
||||
})
|
||||
|
||||
Vue.component("node-ip-address-clusters-selector", {
|
||||
props: ["vClusters"],
|
||||
mounted: function () {
|
||||
this.checkClusters()
|
||||
},
|
||||
data: function () {
|
||||
let clusters = this.vClusters
|
||||
if (clusters == null) {
|
||||
clusters = []
|
||||
}
|
||||
return {
|
||||
clusters: clusters,
|
||||
hasCheckedCluster: false,
|
||||
clustersVisible: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkClusters: function () {
|
||||
let that = this
|
||||
|
||||
let b = false
|
||||
this.clusters.forEach(function (cluster) {
|
||||
if (cluster.isChecked) {
|
||||
b = true
|
||||
}
|
||||
})
|
||||
|
||||
this.hasCheckedCluster = b
|
||||
|
||||
return b
|
||||
},
|
||||
changeCluster: function (cluster) {
|
||||
cluster.isChecked = !cluster.isChecked
|
||||
this.checkClusters()
|
||||
},
|
||||
showClusters: function () {
|
||||
this.clustersVisible = !this.clustersVisible
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<span v-if="!hasCheckedCluster">默认用于所有集群 <a href="" @click.prevent="showClusters">修改 <i class="icon angle" :class="{down: !clustersVisible, up:clustersVisible}"></i></a></span>
|
||||
<div v-if="hasCheckedCluster">
|
||||
<span v-for="cluster in clusters" class="ui label basic small" v-if="cluster.isChecked">{{cluster.name}}</span> <a href="" @click.prevent="showClusters">修改 <i class="icon angle" :class="{down: !clustersVisible, up:clustersVisible}"></i></a>
|
||||
<p class="comment">当前IP仅在所选集群中有效。</p>
|
||||
</div>
|
||||
<div v-show="clustersVisible">
|
||||
<div class="ui divider"></div>
|
||||
<checkbox v-for="cluster in clusters" :v-value="cluster.id" :value="cluster.isChecked ? cluster.id : 0" style="margin-right: 1em" @input="changeCluster(cluster)" name="clusterIds">
|
||||
{{cluster.name}}
|
||||
</checkbox>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
|
||||
// 节点登录推荐端口
|
||||
Vue.component("node-login-suggest-ports", {
|
||||
data: function () {
|
||||
@@ -17143,11 +17326,17 @@ Vue.component("node-group-selector", {
|
||||
|
||||
// 节点IP地址管理(标签形式)
|
||||
Vue.component("node-ip-addresses-box", {
|
||||
props: ["v-ip-addresses", "role"],
|
||||
props: ["v-ip-addresses", "role", "v-node-id"],
|
||||
data: function () {
|
||||
let nodeId = this.vNodeId
|
||||
if (nodeId == null) {
|
||||
nodeId = 0
|
||||
}
|
||||
|
||||
return {
|
||||
ipAddresses: (this.vIpAddresses == null) ? [] : this.vIpAddresses,
|
||||
supportThresholds: this.role != "ns"
|
||||
supportThresholds: this.role != "ns",
|
||||
nodeId: nodeId
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -17156,7 +17345,7 @@ Vue.component("node-ip-addresses-box", {
|
||||
window.UPDATING_NODE_IP_ADDRESS = null
|
||||
|
||||
let that = this;
|
||||
teaweb.popup("/nodes/ipAddresses/createPopup?supportThresholds=" + (this.supportThresholds ? 1 : 0), {
|
||||
teaweb.popup("/nodes/ipAddresses/createPopup?nodeId=" + this.nodeId + "&supportThresholds=" + (this.supportThresholds ? 1 : 0), {
|
||||
callback: function (resp) {
|
||||
that.ipAddresses.push(resp.data.ipAddress);
|
||||
},
|
||||
@@ -17167,10 +17356,10 @@ Vue.component("node-ip-addresses-box", {
|
||||
|
||||
// 修改地址
|
||||
updateIPAddress: function (index, address) {
|
||||
window.UPDATING_NODE_IP_ADDRESS = address
|
||||
window.UPDATING_NODE_IP_ADDRESS = teaweb.clone(address)
|
||||
|
||||
let that = this;
|
||||
teaweb.popup("/nodes/ipAddresses/updatePopup?supportThresholds=" + (this.supportThresholds ? 1 : 0), {
|
||||
teaweb.popup("/nodes/ipAddresses/updatePopup?nodeId=" + this.nodeId + "&supportThresholds=" + (this.supportThresholds ? 1 : 0), {
|
||||
callback: function (resp) {
|
||||
Vue.set(that.ipAddresses, index, resp.data.ipAddress);
|
||||
},
|
||||
@@ -17201,6 +17390,11 @@ Vue.component("node-ip-addresses-box", {
|
||||
<span class="small red" v-if="!address.isUp" title="已下线">[down]</span>
|
||||
<span class="small" v-if="address.thresholds != null && address.thresholds.length > 0">[{{address.thresholds.length}}个阈值]</span>
|
||||
|
||||
<span v-if="address.clusters != null && address.clusters.length > 0">
|
||||
<span class="small grey">专属集群:[</span><span v-for="(cluster, index) in address.clusters" class="small grey">{{cluster.name}}<span v-if="index < address.clusters.length - 1">,</span></span><span class="small grey">]</span>
|
||||
|
||||
</span>
|
||||
|
||||
<a href="" title="修改" @click.prevent="updateIPAddress(index, address)"><i class="icon pencil small"></i></a>
|
||||
<a href="" title="删除" @click.prevent="removeIPAddress(index)"><i class="icon remove"></i></a>
|
||||
</div>
|
||||
@@ -18249,6 +18443,183 @@ Vue.component("dns-resolver-config-box", {
|
||||
</div>`
|
||||
})
|
||||
|
||||
Vue.component("ad-instance-objects-box", {
|
||||
props: ["v-objects", "v-user-id"],
|
||||
mounted: function () {
|
||||
this.getUserServers(1)
|
||||
},
|
||||
data: function () {
|
||||
let objects = this.vObjects
|
||||
if (objects == null) {
|
||||
objects = []
|
||||
}
|
||||
|
||||
let objectCodes = []
|
||||
objects.forEach(function (v) {
|
||||
objectCodes.push(v.code)
|
||||
})
|
||||
|
||||
return {
|
||||
userId: this.vUserId,
|
||||
objects: objects,
|
||||
objectCodes: objectCodes,
|
||||
isAdding: true,
|
||||
|
||||
servers: [],
|
||||
serversIsLoading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add: function () {
|
||||
this.isAdding = true
|
||||
},
|
||||
cancel: function () {
|
||||
this.isAdding = false
|
||||
},
|
||||
remove: function (index) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除此防护对象吗?", function () {
|
||||
that.objects.$remove(index)
|
||||
that.notifyChange()
|
||||
})
|
||||
},
|
||||
removeObjectCode: function (objectCode) {
|
||||
let index = -1
|
||||
this.objectCodes.forEach(function (v, k) {
|
||||
if (objectCode == v) {
|
||||
index = k
|
||||
}
|
||||
})
|
||||
if (index >= 0) {
|
||||
this.objects.$remove(index)
|
||||
this.notifyChange()
|
||||
}
|
||||
},
|
||||
getUserServers: function (page) {
|
||||
if (Tea.Vue == null) {
|
||||
let that = this
|
||||
setTimeout(function () {
|
||||
that.getUserServers(page)
|
||||
}, 100)
|
||||
return
|
||||
}
|
||||
|
||||
let that = this
|
||||
this.serversIsLoading = true
|
||||
Tea.Vue.$post(".userServers")
|
||||
.params({
|
||||
userId: this.userId,
|
||||
page: page,
|
||||
pageSize: 5
|
||||
})
|
||||
.success(function (resp) {
|
||||
that.servers = resp.data.servers
|
||||
|
||||
that.$refs.serverPage.updateMax(resp.data.page.max)
|
||||
that.serversIsLoading = false
|
||||
})
|
||||
.error(function () {
|
||||
that.serversIsLoading = false
|
||||
})
|
||||
},
|
||||
changeServerPage: function (page) {
|
||||
this.getUserServers(page)
|
||||
},
|
||||
selectServerObject: function (server) {
|
||||
if (this.existObjectCode("server:" + server.id)) {
|
||||
return
|
||||
}
|
||||
|
||||
this.objects.push({
|
||||
"type": "server",
|
||||
"code": "server:" + server.id,
|
||||
|
||||
"id": server.id,
|
||||
"name": server.name
|
||||
})
|
||||
this.notifyChange()
|
||||
},
|
||||
notifyChange: function () {
|
||||
let objectCodes = []
|
||||
this.objects.forEach(function (v) {
|
||||
objectCodes.push(v.code)
|
||||
})
|
||||
this.objectCodes = objectCodes
|
||||
},
|
||||
existObjectCode: function (objectCode) {
|
||||
let found = false
|
||||
this.objects.forEach(function (v) {
|
||||
if (v.code == objectCode) {
|
||||
found = true
|
||||
}
|
||||
})
|
||||
return found
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" name="objectCodesJSON" :value="JSON.stringify(objectCodes)"/>
|
||||
|
||||
<!-- 已有对象 -->
|
||||
<div>
|
||||
<div v-if="objects.length == 0"><span class="grey">暂时还没有设置任何防护对象。</span></div>
|
||||
<div v-if="objects.length > 0">
|
||||
<table class="ui table">
|
||||
<tr>
|
||||
<td class="title">已选中防护对象</td>
|
||||
<td>
|
||||
<div v-for="(object, index) in objects" class="ui label basic small" style="margin-bottom: 0.5em">
|
||||
<span v-if="object.type == 'server'">网站服务:{{object.name}}</span>
|
||||
<a href="" title="删除" @click.prevent="remove(index)"><i class="icon remove small"></i></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="margin"></div>
|
||||
|
||||
<!-- 添加表单 -->
|
||||
<div v-if="isAdding">
|
||||
<table class="ui table celled">
|
||||
<tr>
|
||||
<td class="title">对象类型</td>
|
||||
<td>网站服务</td>
|
||||
</tr>
|
||||
<!-- 服务列表 -->
|
||||
<tr>
|
||||
<td>服务列表</td>
|
||||
<td>
|
||||
<span v-if="serversIsLoading">加载中...</span>
|
||||
<div v-if="!serversIsLoading && servers.length == 0">暂时还没有可选的网站服务。</div>
|
||||
<table class="ui table" v-show="!serversIsLoading && servers.length > 0">
|
||||
<thead class="full-width">
|
||||
<tr>
|
||||
<th>网站服务名称</th>
|
||||
<th class="one op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="server in servers">
|
||||
<td style="background: white">{{server.name}}</td>
|
||||
<td>
|
||||
<a href="" @click.prevent="selectServerObject(server)" v-if="!existObjectCode('server:' + server.id)">选中</a>
|
||||
<a href="" @click.prevent="removeObjectCode('server:' + server.id)" v-else><span class="red">取消</span></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<js-page ref="serverPage" @change="changeServerPage"></js-page>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 添加按钮 -->
|
||||
<div v-if="!isAdding">
|
||||
<button class="ui button tiny" type="button" @click.prevent="add">+</button>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
|
||||
Vue.component("grant-selector", {
|
||||
props: ["v-grant", "v-node-cluster-id", "v-ns-cluster-id"],
|
||||
data: function () {
|
||||
@@ -18329,9 +18700,9 @@ window.REQUEST_COND_COMPONENTS = [{"type":"url-extension","name":"URL扩展名",
|
||||
|
||||
window.REQUEST_COND_OPERATORS = [{"description":"判断是否正则表达式匹配","name":"正则表达式匹配","op":"regexp"},{"description":"判断是否正则表达式不匹配","name":"正则表达式不匹配","op":"not regexp"},{"description":"使用字符串对比参数值是否相等于某个值","name":"字符串等于","op":"eq"},{"description":"参数值包含某个前缀","name":"字符串前缀","op":"prefix"},{"description":"参数值包含某个后缀","name":"字符串后缀","op":"suffix"},{"description":"参数值包含另外一个字符串","name":"字符串包含","op":"contains"},{"description":"参数值不包含另外一个字符串","name":"字符串不包含","op":"not contains"},{"description":"使用字符串对比参数值是否不相等于某个值","name":"字符串不等于","op":"not"},{"description":"判断参数值在某个列表中","name":"在列表中","op":"in"},{"description":"判断参数值不在某个列表中","name":"不在列表中","op":"not in"},{"description":"判断小写的扩展名(不带点)在某个列表中","name":"扩展名","op":"file ext"},{"description":"判断MimeType在某个列表中,支持类似于image/*的语法","name":"MimeType","op":"mime type"},{"description":"判断版本号在某个范围内,格式为version1,version2","name":"版本号范围","op":"version range"},{"description":"将参数转换为整数数字后进行对比","name":"整数等于","op":"eq int"},{"description":"将参数转换为可以有小数的浮点数字进行对比","name":"浮点数等于","op":"eq float"},{"description":"将参数转换为数字进行对比","name":"数字大于","op":"gt"},{"description":"将参数转换为数字进行对比","name":"数字大于等于","op":"gte"},{"description":"将参数转换为数字进行对比","name":"数字小于","op":"lt"},{"description":"将参数转换为数字进行对比","name":"数字小于等于","op":"lte"},{"description":"对整数参数值取模,除数为10,对比值为余数","name":"整数取模10","op":"mod 10"},{"description":"对整数参数值取模,除数为100,对比值为余数","name":"整数取模100","op":"mod 100"},{"description":"对整数参数值取模,对比值格式为:除数,余数,比如10,1","name":"整数取模","op":"mod"},{"description":"将参数转换为IP进行对比","name":"IP等于","op":"eq ip"},{"description":"将参数转换为IP进行对比","name":"IP大于","op":"gt ip"},{"description":"将参数转换为IP进行对比","name":"IP大于等于","op":"gte ip"},{"description":"将参数转换为IP进行对比","name":"IP小于","op":"lt ip"},{"description":"将参数转换为IP进行对比","name":"IP小于等于","op":"lte ip"},{"description":"IP在某个范围之内,范围格式可以是英文逗号分隔的\u003ccode-label\u003e开始IP,结束IP\u003c/code-label\u003e,比如\u003ccode-label\u003e192.168.1.100,192.168.2.200\u003c/code-label\u003e,或者CIDR格式的ip/bits,比如\u003ccode-label\u003e192.168.2.1/24\u003c/code-label\u003e","name":"IP范围","op":"ip range"},{"description":"对IP参数值取模,除数为10,对比值为余数","name":"IP取模10","op":"ip mod 10"},{"description":"对IP参数值取模,除数为100,对比值为余数","name":"IP取模100","op":"ip mod 100"},{"description":"对IP参数值取模,对比值格式为:除数,余数,比如10,1","name":"IP取模","op":"ip mod"},{"description":"判断参数值解析后的文件是否存在","name":"文件存在","op":"file exist"},{"description":"判断参数值解析后的文件是否不存在","name":"文件不存在","op":"file not exist"}]
|
||||
|
||||
window.REQUEST_VARIABLES = [{"code":"${edgeVersion}","description":"","name":"边缘节点版本"},{"code":"${remoteAddr}","description":"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取,适合前端有别的反向代理服务时使用,存在伪造的风险","name":"客户端地址(IP)"},{"code":"${rawRemoteAddr}","description":"返回直接连接服务的客户端原始IP地址","name":"客户端地址(IP)"},{"code":"${remotePort}","description":"","name":"客户端端口"},{"code":"${remoteUser}","description":"","name":"客户端用户名"},{"code":"${requestURI}","description":"比如/hello?name=lily","name":"请求URI"},{"code":"${requestPath}","description":"比如/hello","name":"请求路径(不包括参数)"},{"code":"${requestURL}","description":"比如https://example.com/hello?name=lily","name":"完整的请求URL"},{"code":"${requestLength}","description":"","name":"请求内容长度"},{"code":"${requestMethod}","description":"比如GET、POST","name":"请求方法"},{"code":"${requestFilename}","description":"","name":"请求文件路径"},{"code":"${scheme}","description":"","name":"请求协议,http或https"},{"code":"${proto}","description:":"类似于HTTP/1.0","name":"包含版本的HTTP请求协议"},{"code":"${timeISO8601}","description":"比如2018-07-16T23:52:24.839+08:00","name":"ISO 8601格式的时间"},{"code":"${timeLocal}","description":"比如17/Jul/2018:09:52:24 +0800","name":"本地时间"},{"code":"${msec}","description":"比如1531756823.054","name":"带有毫秒的时间"},{"code":"${timestamp}","description":"","name":"unix时间戳,单位为秒"},{"code":"${host}","description":"","name":"主机名"},{"code":"${cname}","description":"比如38b48e4f.goedge.cn","name":"当前网站的CNAME"},{"code":"${serverName}","description":"","name":"接收请求的服务器名"},{"code":"${serverPort}","description":"","name":"接收请求的服务器端口"},{"code":"${referer}","description":"","name":"请求来源URL"},{"code":"${referer.host}","description":"","name":"请求来源URL域名"},{"code":"${userAgent}","description":"","name":"客户端信息"},{"code":"${contentType}","description":"","name":"请求头部的Content-Type"},{"code":"${cookies}","description":"","name":"所有cookie组合字符串"},{"code":"${cookie.NAME}","description":"","name":"单个cookie值"},{"code":"${isArgs}","description":"如果URL有参数,则值为`?`;否则,则值为空","name":"问号(?)标记"},{"code":"${args}","description":"","name":"所有参数组合字符串"},{"code":"${arg.NAME}","description":"","name":"单个参数值"},{"code":"${headers}","description":"","name":"所有Header信息组合字符串"},{"code":"${header.NAME}","description":"","name":"单个Header值"},{"code":"${geo.country.name}","description":"","name":"国家/地区名称"},{"code":"${geo.country.id}","description":"","name":"国家/地区ID"},{"code":"${geo.province.name}","description":"目前只包含中国省份","name":"省份名称"},{"code":"${geo.province.id}","description":"目前只包含中国省份","name":"省份ID"},{"code":"${geo.city.name}","description":"目前只包含中国城市","name":"城市名称"},{"code":"${geo.city.id}","description":"目前只包含中国城市","name":"城市名称"},{"code":"${isp.name}","description":"","name":"ISP服务商名称"},{"code":"${isp.id}","description":"","name":"ISP服务商ID"},{"code":"${browser.os.name}","description":"客户端所在操作系统名称","name":"操作系统名称"},{"code":"${browser.os.version}","description":"客户端所在操作系统版本","name":"操作系统版本"},{"code":"${browser.name}","description":"客户端浏览器名称","name":"浏览器名称"},{"code":"${browser.version}","description":"客户端浏览器版本","name":"浏览器版本"},{"code":"${browser.isMobile}","description":"如果客户端是手机,则值为1,否则为0","name":"手机标识"}]
|
||||
window.REQUEST_VARIABLES = [{"code":"${edgeVersion}","description":"","name":"边缘节点版本"},{"code":"${remoteAddr}","description":"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取,适合前端有别的反向代理服务时使用,存在伪造的风险","name":"客户端地址(IP)"},{"code":"${rawRemoteAddr}","description":"返回直接连接服务的客户端原始IP地址","name":"客户端地址(IP)"},{"code":"${remotePort}","description":"","name":"客户端端口"},{"code":"${remoteUser}","description":"","name":"客户端用户名"},{"code":"${requestURI}","description":"比如/hello?name=lily","name":"请求URI"},{"code":"${requestPath}","description":"比如/hello","name":"请求路径(不包括参数)"},{"code":"${requestURL}","description":"比如https://example.com/hello?name=lily","name":"完整的请求URL"},{"code":"${requestLength}","description":"","name":"请求内容长度"},{"code":"${requestMethod}","description":"比如GET、POST","name":"请求方法"},{"code":"${requestFilename}","description":"","name":"请求文件路径"},{"code":"${requestPathExtension}","description":"请求路径中的文件扩展名,包括点符号,比如.html、.png","name":"请求文件扩展名"},{"code":"${requestPathLowerExtension}","description":"请求路径中的文件扩展名,其中大写字母会被自动转换为小写,包括点符号,比如.html、.png","name":"请求文件小写扩展名"},{"code":"${scheme}","description":"","name":"请求协议,http或https"},{"code":"${proto}","description:":"类似于HTTP/1.0","name":"包含版本的HTTP请求协议"},{"code":"${timeISO8601}","description":"比如2018-07-16T23:52:24.839+08:00","name":"ISO 8601格式的时间"},{"code":"${timeLocal}","description":"比如17/Jul/2018:09:52:24 +0800","name":"本地时间"},{"code":"${msec}","description":"比如1531756823.054","name":"带有毫秒的时间"},{"code":"${timestamp}","description":"","name":"unix时间戳,单位为秒"},{"code":"${host}","description":"","name":"主机名"},{"code":"${cname}","description":"比如38b48e4f.goedge.cn","name":"当前网站的CNAME"},{"code":"${serverName}","description":"","name":"接收请求的服务器名"},{"code":"${serverPort}","description":"","name":"接收请求的服务器端口"},{"code":"${referer}","description":"","name":"请求来源URL"},{"code":"${referer.host}","description":"","name":"请求来源URL域名"},{"code":"${userAgent}","description":"","name":"客户端信息"},{"code":"${contentType}","description":"","name":"请求头部的Content-Type"},{"code":"${cookies}","description":"","name":"所有cookie组合字符串"},{"code":"${cookie.NAME}","description":"","name":"单个cookie值"},{"code":"${isArgs}","description":"如果URL有参数,则值为`?`;否则,则值为空","name":"问号(?)标记"},{"code":"${args}","description":"","name":"所有参数组合字符串"},{"code":"${arg.NAME}","description":"","name":"单个参数值"},{"code":"${headers}","description":"","name":"所有Header信息组合字符串"},{"code":"${header.NAME}","description":"","name":"单个Header值"},{"code":"${geo.country.name}","description":"","name":"国家/地区名称"},{"code":"${geo.country.id}","description":"","name":"国家/地区ID"},{"code":"${geo.province.name}","description":"目前只包含中国省份","name":"省份名称"},{"code":"${geo.province.id}","description":"目前只包含中国省份","name":"省份ID"},{"code":"${geo.city.name}","description":"目前只包含中国城市","name":"城市名称"},{"code":"${geo.city.id}","description":"目前只包含中国城市","name":"城市名称"},{"code":"${isp.name}","description":"","name":"ISP服务商名称"},{"code":"${isp.id}","description":"","name":"ISP服务商ID"},{"code":"${browser.os.name}","description":"客户端所在操作系统名称","name":"操作系统名称"},{"code":"${browser.os.version}","description":"客户端所在操作系统版本","name":"操作系统版本"},{"code":"${browser.name}","description":"客户端浏览器名称","name":"浏览器名称"},{"code":"${browser.version}","description":"客户端浏览器版本","name":"浏览器版本"},{"code":"${browser.isMobile}","description":"如果客户端是手机,则值为1,否则为0","name":"手机标识"}]
|
||||
|
||||
window.METRIC_HTTP_KEYS = [{"name":"客户端地址(IP)","code":"${remoteAddr}","description":"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取,适用于前端可能有别的反向代理的情形,存在被伪造的可能","icon":""},{"name":"直接客户端地址(IP)","code":"${rawRemoteAddr}","description":"返回直接连接服务的客户端原始IP地址","icon":""},{"name":"客户端用户名","code":"${remoteUser}","description":"通过基本认证填入的用户名","icon":""},{"name":"请求URI","code":"${requestURI}","description":"包含参数,比如/hello?name=lily","icon":""},{"name":"请求路径","code":"${requestPath}","description":"不包含参数,比如/hello","icon":""},{"name":"完整URL","code":"${requestURL}","description":"比如https://example.com/hello?name=lily","icon":""},{"name":"请求方法","code":"${requestMethod}","description":"比如GET、POST等","icon":""},{"name":"请求协议Scheme","code":"${scheme}","description":"http或https","icon":""},{"name":"文件扩展名","code":"${requestPathExtension}","description":"请求路径中的文件扩展名,包括点符号,比如.html、.png","icon":""},{"name":"主机名","code":"${host}","description":"通常是请求的域名","icon":""},{"name":"请求协议Proto","code":"${proto}","description":"包含版本的HTTP请求协议,类似于HTTP/1.0","icon":""},{"name":"HTTP协议","code":"${proto}","description":"包含版本的HTTP请求协议,类似于HTTP/1.0","icon":""},{"name":"URL参数值","code":"${arg.NAME}","description":"单个URL参数值","icon":""},{"name":"请求来源URL","code":"${referer}","description":"请求来源Referer URL","icon":""},{"name":"请求来源URL域名","code":"${referer.host}","description":"请求来源Referer URL域名","icon":""},{"name":"Header值","code":"${header.NAME}","description":"单个Header值,比如${header.User-Agent}","icon":""},{"name":"Cookie值","code":"${cookie.NAME}","description":"单个cookie值,比如${cookie.sid}","icon":""},{"name":"状态码","code":"${status}","description":"","icon":""},{"name":"响应的Content-Type值","code":"${response.contentType}","description":"","icon":""}]
|
||||
window.METRIC_HTTP_KEYS = [{"name":"客户端地址(IP)","code":"${remoteAddr}","description":"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取,适用于前端可能有别的反向代理的情形,存在被伪造的可能","icon":""},{"name":"直接客户端地址(IP)","code":"${rawRemoteAddr}","description":"返回直接连接服务的客户端原始IP地址","icon":""},{"name":"客户端用户名","code":"${remoteUser}","description":"通过基本认证填入的用户名","icon":""},{"name":"请求URI","code":"${requestURI}","description":"包含参数,比如/hello?name=lily","icon":""},{"name":"请求路径","code":"${requestPath}","description":"不包含参数,比如/hello","icon":""},{"name":"完整URL","code":"${requestURL}","description":"比如https://example.com/hello?name=lily","icon":""},{"name":"请求方法","code":"${requestMethod}","description":"比如GET、POST等","icon":""},{"name":"请求协议Scheme","code":"${scheme}","description":"http或https","icon":""},{"name":"文件扩展名","code":"${requestPathExtension}","description":"请求路径中的文件扩展名,包括点符号,比如.html、.png","icon":""},{"name":"小写文件扩展名","code":"${requestPathLowerExtension}","description":"请求路径中的文件扩展名小写形式,包括点符号,比如.html、.png","icon":""},{"name":"主机名","code":"${host}","description":"通常是请求的域名","icon":""},{"name":"请求协议Proto","code":"${proto}","description":"包含版本的HTTP请求协议,类似于HTTP/1.0","icon":""},{"name":"HTTP协议","code":"${proto}","description":"包含版本的HTTP请求协议,类似于HTTP/1.0","icon":""},{"name":"URL参数值","code":"${arg.NAME}","description":"单个URL参数值","icon":""},{"name":"请求来源URL","code":"${referer}","description":"请求来源Referer URL","icon":""},{"name":"请求来源URL域名","code":"${referer.host}","description":"请求来源Referer URL域名","icon":""},{"name":"Header值","code":"${header.NAME}","description":"单个Header值,比如${header.User-Agent}","icon":""},{"name":"Cookie值","code":"${cookie.NAME}","description":"单个cookie值,比如${cookie.sid}","icon":""},{"name":"状态码","code":"${status}","description":"","icon":""},{"name":"响应的Content-Type值","code":"${response.contentType}","description":"","icon":""}]
|
||||
|
||||
window.IP_ADDR_THRESHOLD_ITEMS = [{"code":"nodeAvgRequests","description":"当前节点在单位时间内接收到的平均请求数。","name":"节点平均请求数","unit":"个"},{"code":"nodeAvgTrafficOut","description":"当前节点在单位时间内发送的下行流量。","name":"节点平均下行流量","unit":"M"},{"code":"nodeAvgTrafficIn","description":"当前节点在单位时间内接收的上行流量。","name":"节点平均上行流量","unit":"M"},{"code":"nodeHealthCheck","description":"当前节点健康检查结果。","name":"节点健康检查结果","unit":""},{"code":"connectivity","description":"通过区域监控得到的当前IP地址的连通性数值,取值在0和100之间。","name":"IP连通性","unit":"%"},{"code":"groupAvgRequests","description":"当前节点所在分组在单位时间内接收到的平均请求数。","name":"分组平均请求数","unit":"个"},{"code":"groupAvgTrafficOut","description":"当前节点所在分组在单位时间内发送的下行流量。","name":"分组平均下行流量","unit":"M"},{"code":"groupAvgTrafficIn","description":"当前节点所在分组在单位时间内接收的上行流量。","name":"分组平均上行流量","unit":"M"},{"code":"clusterAvgRequests","description":"当前节点所在集群在单位时间内接收到的平均请求数。","name":"集群平均请求数","unit":"个"},{"code":"clusterAvgTrafficOut","description":"当前节点所在集群在单位时间内发送的下行流量。","name":"集群平均下行流量","unit":"M"},{"code":"clusterAvgTrafficIn","description":"当前节点所在集群在单位时间内接收的上行流量。","name":"集群平均上行流量","unit":"M"}]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user