diff --git a/dashboard/src2/components/JsiteDomainModifyDNSServerDialog.vue b/dashboard/src2/components/JsiteDomainModifyDNSServerDialog.vue index 601f3a8..b5d75f8 100644 --- a/dashboard/src2/components/JsiteDomainModifyDNSServerDialog.vue +++ b/dashboard/src2/components/JsiteDomainModifyDNSServerDialog.vue @@ -13,6 +13,7 @@ type="text" class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" :class="{ 'border-red-300': errors.dns1 }" + @blur="validateDNSField('dns1', '主DNS服务器')" />

{{ errors.dns1 }}

@@ -27,6 +28,7 @@ type="text" class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" :class="{ 'border-red-300': errors.dns2 }" + @blur="validateDNSField('dns2', '辅DNS服务器')" />

{{ errors.dns2 }}

@@ -40,7 +42,10 @@ v-model="dnsServers.dns3" type="text" class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" + :class="{ 'border-red-300': errors.dns3 }" + @blur="validateDNSField('dns3', '第三个DNS服务器')" /> +

{{ errors.dns3 }}

@@ -52,7 +57,10 @@ v-model="dnsServers.dns4" type="text" class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" + :class="{ 'border-red-300': errors.dns4 }" + @blur="validateDNSField('dns4', '第四个DNS服务器')" /> +

{{ errors.dns4 }}

@@ -64,7 +72,10 @@ v-model="dnsServers.dns5" type="text" class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" + :class="{ 'border-red-300': errors.dns5 }" + @blur="validateDNSField('dns5', '第五个DNS服务器')" /> +

{{ errors.dns5 }}

@@ -76,7 +87,10 @@ v-model="dnsServers.dns6" type="text" class="w-full px-3 py-1.5 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" + :class="{ 'border-red-300': errors.dns6 }" + @blur="validateDNSField('dns6', '第六个DNS服务器')" /> +

{{ errors.dns6 }}

@@ -154,40 +168,14 @@ export default { return Object.keys(this.errors).length > 0; } }, + resources: { modifyDNSServer() { return { url: 'jcloud.api.domain_west.west_domain_modify_dns_server', validate() { - this.errors = {}; - - if (!this.dnsServers.dns1) { - this.errors.dns1 = '主DNS服务器不能为空'; - } else if (!this.isValidDNSFormat(this.dnsServers.dns1)) { - this.errors.dns1 = '主DNS服务器格式不正确'; - } - - if (!this.dnsServers.dns2) { - this.errors.dns2 = '辅DNS服务器不能为空'; - } else if (!this.isValidDNSFormat(this.dnsServers.dns2)) { - this.errors.dns2 = '辅DNS服务器格式不正确'; - } - - // 验证可选的DNS服务器格式 - if (this.dnsServers.dns3 && !this.isValidDNSFormat(this.dnsServers.dns3)) { - this.errors.dns3 = '第三个DNS服务器格式不正确'; - } - if (this.dnsServers.dns4 && !this.isValidDNSFormat(this.dnsServers.dns4)) { - this.errors.dns4 = '第四个DNS服务器格式不正确'; - } - if (this.dnsServers.dns5 && !this.isValidDNSFormat(this.dnsServers.dns5)) { - this.errors.dns5 = '第五个DNS服务器格式不正确'; - } - if (this.dnsServers.dns6 && !this.isValidDNSFormat(this.dnsServers.dns6)) { - this.errors.dns6 = '第六个DNS服务器格式不正确'; - } - - if (Object.keys(this.errors).length > 0) { + // 实时验证已经完成,这里只需要检查是否有错误 + if (this.hasErrors) { throw new DashboardError('请检查DNS服务器格式'); } }, @@ -219,20 +207,92 @@ export default { this.error = null; this.$resources.modifyDNSServer.submit({ domain: this.domainDoc?.domain, - dns1: this.dnsServers.dns1, - dns2: this.dnsServers.dns2, - dns3: this.dnsServers.dns3 || undefined, - dns4: this.dnsServers.dns4 || undefined, - dns5: this.dnsServers.dns5 || undefined, - dns6: this.dnsServers.dns6 || undefined + dns1: this.dnsServers.dns1?.trim() || '', + dns2: this.dnsServers.dns2?.trim() || '', + dns3: this.dnsServers.dns3?.trim() || undefined, + dns4: this.dnsServers.dns4?.trim() || undefined, + dns5: this.dnsServers.dns5?.trim() || undefined, + dns6: this.dnsServers.dns6?.trim() || undefined }); }, + validateDNSField(fieldName, fieldLabel) { + const value = this.dnsServers[fieldName]; + + // 清除该字段的错误 + if (this.errors[fieldName]) { + delete this.errors[fieldName]; + } + + // 如果是必填字段且为空,不显示错误(让用户继续输入) + if ((fieldName === 'dns1' || fieldName === 'dns2') && !value) { + return; + } + + // 检查是否有首尾空格 + if (value && (value !== value.trim())) { + this.errors[fieldName] = `${fieldLabel}不能包含首尾空格`; + return; + } + + // 如果字段有值但格式不正确,显示错误 + if (value && !this.isValidDNSFormat(value)) { + this.errors[fieldName] = `${fieldLabel}格式不正确`; + } + }, isValidDNSFormat(dns) { if (!dns) return false; - // 简单的DNS格式验证 - const dnsRegex = /^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$/; - return dnsRegex.test(dns) && dns.length >= 3 && dns.length <= 253; + // 检查长度 + if (dns.length < 3 || dns.length > 253) { + return false; + } + + // 检查是否包含至少一个点号(域名必须有点号分隔) + if (!dns.includes('.')) { + return false; + } + + // 检查是否以点号开头或结尾 + if (dns.startsWith('.') || dns.endsWith('.')) { + return false; + } + + // 检查是否包含连续的点号 + if (dns.includes('..')) { + return false; + } + + // 分割域名部分进行详细验证 + const parts = dns.split('.'); + + for (let part of parts) { + // 每个部分不能为空 + if (!part) { + return false; + } + + // 每个部分长度不能超过63个字符 + if (part.length > 63) { + return false; + } + + // 每个部分不能以连字符开头或结尾 + if (part.startsWith('-') || part.endsWith('-')) { + return false; + } + + // 每个部分只能包含字母、数字和连字符 + if (!/^[a-zA-Z0-9-]+$/.test(part)) { + return false; + } + + // 顶级域名(最后一部分)不能全是数字 + if (parts.indexOf(part) === parts.length - 1 && /^\d+$/.test(part)) { + return false; + } + } + + return true; } } };