Dreamweaver 怎么实现 JavaScript 表单验证?失效原因与现代写法
在 Dreamweaver(DW)里做表单验证,是不少建站新手的第一课:可视化里点了“检查表单”行为,却发现要么完全没反应,要么一填就报错。问题出在DW 生成的 JS 只是老式简单校验,现代浏览器与业务场景都需要重写。本文把 DW 的做法讲清,并给出可用的替代方案。

一、DW 的“检查表单”行为做了什么
DW 里选中文本框 → Behaviors(行为)面板 → Check Form(检查表单),它会插入一段形如 MMP_validation / validateForm() 的函数,并在 <form onsubmit="return validateForm();" 上挂钩。生成的核心逻辑大致是:
function validateForm(theForm) {
if (theForm.name.value == '') {
alert('Please enter a value for the "name" field');
theForm.name.focus();
return false;
}
if (theForm.email.value.search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) == -1) {
alert('Please enter a valid email address');
theForm.email.focus();
return false;
}
return true;
}
它支持的校验类型只有:空值、必需、数字/字母数字、复选框至少选一项、单选必选、邮件格式。所以它只能应付最基础的场景。
二、DW 表单验证常见的三个失效原因
- ① 字段命名冲突:DW 用
theForm.name取元素,但如果 input 的name恰好叫name,会与 form 自身的name属性冲突(form.name优先返回字符串属性),导致取到 undefined。这是最常见的“DW 验证死活不触发”的原因。解决:字段改名为username,或用theForm.elements['name']。 - ② 行为挂在 form 而不是 submit 按钮:按钮若是
type="button"且绑了 onclick 提交,onsubmit 根本不会触发(form.submit()不会触发 submit 事件)。要用type="submit"或手动调用校验函数。 - ③ 多个表单同名/同名行为覆盖:DW 生成的函数名固定,页面复制粘贴出两份时后一份会覆盖前者。
三、更好的做法:HTML5 原生约束验证
现代浏览器自带约束验证 API,绝大多数基础校验不需要写 JS:
<form id="regForm" novalidate>
<input name="username" required minlength="3" maxlength="20"
pattern="[A-Za-z0-9_]{3,20}">
<input name="email" type="email" required>
<input name="age" type="number" min="1" max="120">
<input name="phone" type="tel" pattern="1[3-9]\d{9}" required>
<button type="submit">注册</button>
</form>
浏览器会自动判断:required(空)、minlength/maxlength、pattern(正则)、type=email/url/number 格式、min/max/step、max 长度。自定义提示可用 setCustomValidity():
const f = document.getElementById('regForm');
f.addEventListener('invalid', e => {
const el = e.target;
if (el.validity.valueMissing) el.setCustomValidity('请填写此项');
else if (el.validity.patternMismatch) el.setCustomValidity('格式不正确');
else el.setCustomValidity('');
}, true); // 注意第三个参数 true,invalid 不冒泡必须捕获
提交前统一校验:if (!f.checkValidity()) { f.reportValidity(); return; }。
四、手写一个可读性好的校验函数
需要复杂规则(两次密码一致、验证码、手机号查重)时用声明式配置最省事:
const rules = {
username: [[v => v.length >= 3, '用户名至少 3 个字符'],
[v => /^[A-Za-z0-9_]+$/.test(v), '只能用字母数字下划线']],
email: [[v => /\S+@\S+\.\S+/.test(v), '邮箱格式不正确']],
password: [[v => v.length >= 8, '密码至少 8 位'],
[v => /[A-Z]/.test(v) && /\d/.test(v), '需含大写字母和数字']],
};
function validate(data) {
const errors = {};
for (const [k, list] of Object.entries(rules)) {
for (const [test, msg] of list) {
if (data[k] && !test(data[k])) { (errors[k] ||= []).push(msg); break; }
}
}
if (data.password !== data.confirm) (errors.confirm ||= []).push('两次输入不一致');
return errors;
}
要点三条:空值不套用格式规则(否则一边输一边报“格式错误”,体验很差)、一次只报第一条、服务端必须重跑同一套规则。
五、前端校验只是体验,后端才是防线
必须建立这个认知:浏览器 F12 就能删掉 required、绕过所有 JS,甚至直接用 curl 提交。后端 PHP 端的对应校验:
$data = trim($_POST['username'] ?? '');
if ($data === '' || mb_strlen($data) < 3 || mb_strlen($data) > 20
|| !preg_match('/^[A-Za-z0-9_]{3,20}$/u', $data)) {
http_response_code(422);
exit(json_encode(['field' => 'username', 'msg' => '用户名格式不正确']));
}
注意 mb_strlen(中文字符数)与 strlen(字节数)的差异;正则加 u 修饰符处理 UTF-8;preg_match 返回 false 时(如超长输入导致 PCRE backtrack limit)也要当失败处理。
六、常见问题 FAQ
问:DW 里的“检查表单”能直接用在生产项目吗?
答:可以但不推荐。它是 alert 弹窗式提示、无样式、中文提示还要手改代码。现代做法用 HTML5 + 少量 JS,或直接用成熟库(Parsley.js、validate.js、各前端框架内置校验)。
问:为什么我加了 pattern 但输什么都提示错误?
答:pattern 隐含首尾锚定(等价 ^(?:...)$),所以不能再自己加 ^ 和 $,也不能包含 /.../ 定界符。
问:novalidate 是干什么的?
答:关掉浏览器默认气泡提示,用于自己接管 UI。但如果只是想让提示更友好,用 setCustomValidity 保留原生气泡更省事。
一句话:DW 的表单行为适合教学与快速原型;真实项目请用「HTML5 约束 + 少量 JS 自定义提示 + 服务端同规则复校验」,三层各司其职。
生产内容,同时打通搜索引擎(SEO)与AI搜索引擎(GEO)流量入口的软件! 点击进入365建站器 »
