渐进增强下如何优雅降级不支持JS的表单提交?
我做了一个带前端验证的注册表单,但用户禁用JS后直接提交会跳转到错误页面。想用渐进增强的方式让表单在无JS时也能正常提交到后端,但不知道怎么组织结构才合理。
目前我的表单是这样写的:
<form action="/register" method="POST">
<input type="email" name="email" required>
<button type="submit">注册</button>
</form>
JS里我拦截了submit事件做校验,但一旦JS失效,表单虽然能提交,但后端返回的错误信息没法友好展示。是不是应该默认就写好服务端渲染的错误提示区域?
后端验证失败后,不要跳转到错误页面,而是返回原页面并带上错误信息。这样不管你有没有JS都能正常展示:
后端模板里先埋好错误容器:
后端处理逻辑:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$email = $_POST['email'] ?? '';
$errors = [];
// 服务端验证是最后防线
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = '请输入有效的邮箱地址';
}
// 数据库层面检查邮箱是否已注册
if ($emailExists) {
$errors[] = '该邮箱已被注册';
}
if (!empty($errors)) {
// 渲染原页面 + 错误信息
render('register', ['errors' => $errors, 'oldEmail' => $email]);
return;
}
// 验证通过,创建用户
createUser($email);
redirect('/success');
}
前端JS的增强就很简单了:
document.querySelector('form').addEventListener('submit', function(e) {
e.preventDefault();
// 这里是增强体验,不是必须的
// 可以用AJAX提交,或者做更复杂的校验
// 失败了就用JS展示错误,成功了跳转
fetch('/register', {
method: 'POST',
body: new FormData(this)
}).then(res => {
if (res.ok) {
location.href = '/success';
} else {
// 用JS更新错误信息,或者直接reload让服务端渲染
location.reload();
}
});
});
总结一下:服务端渲染的错误区域是基础配置,后端验证失败返回原页面而不是跳转错误页,前端JS只是锦上添花。这样禁用JS后表单也能正常提交、正常看到错误提示。