正确做法是不依赖的action和method,手动收集字段并用fetch发送;需调用event.preventdefault()、用formdata取值或转json并设content-type,含文件时勿手动设content-type。

用 fetch 提交表单数据,不刷新页面
直接用 fetch 替代传统表单提交是最轻量、可控性最强的方式。关键不是“阻止 submit 事件”,而是从源头绕过默认行为——不依赖 <form></form> 的 action 和 method,手动收集字段并发送。
常见错误是只调 event.preventDefault() 却没真正取值,或把整个 FormData 当字符串发出去导致后端收不到键值对。
- 用
new FormData(formElement)获取所有已填写字段(自动忽略disabled和空type="file") - 如果后端要求 JSON,得先转成对象再
JSON.stringify(),且记得设请求头Content-Type: application/json - 若含文件上传,
fetch原生支持FormData,**不要手动设Content-Type**,否则浏览器会覆盖 boundary - 提交前检查必填字段,
form.checkValidity()可复用 HTML5 表单验证逻辑
XMLHttpRequest 还值得用吗
在需要兼容 IE10 或必须监听上传进度的场景下,XMLHttpRequest 仍是唯一选择。但它的 API 更冗长,错误处理容易遗漏状态码判断。
典型坑是只监听 onload,却忽略 onerror 或 onabort;还有人把 responseText 当作 JSON 直接 JSON.parse(),结果服务端返回 4xx 错误时抛异常。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 务必用
xhr.status >= 200 && xhr.status 判断成功,不能只看 <code>onload触发 - 上传大文件时,用
xhr.upload.onprogress更新进度条,form.addEventListener("submit", ...)里不能直接return false,得显式event.preventDefault() - IE 中
FormData不支持直接传入<form></form>元素,需逐个append()字段
用 form.requestSubmit() 触发原生验证再异步提交
HTML5 新增的 requestSubmit() 方法能触发内置校验(如 required、pattern),且不触发 submit 事件——适合想保留语义化验证但又不想走传统提交流程的场景。
很多人误以为它会自动提交,其实只是“模拟点击提交按钮”的行为:校验失败时聚焦错误字段并显示提示,成功时才进入你绑定的 submit 监听器,这时再 fetch 才算真正异步提交。
- 必须配合
event.preventDefault()使用,否则校验通过后仍会跳转 - 不能在非表单元素上调用,比如给按钮加
onclick="form.requestSubmit()"是合法的,但document.querySelector("input").requestSubmit()会报错 - 移动端 Safari 对
requestSubmit()支持良好,但旧版 Android WebView 可能不识别,建议降级到form.reportValidity()+ 手动判断
避免重复提交和 loading 状态失控
用户狂点提交按钮导致多次请求,或接口卡住后 loading 按钮无法恢复,是最常被忽略的交互细节。这不是“锦上添花”,而是影响数据一致性的关键。
单纯禁用按钮还不够:如果请求因网络中断而未发出,按钮就永远卡死;或者用户刷新页面后状态丢失,再次提交时后端可能收到重复订单。
- 提交开始时设按钮
disabled并改文字(如 “提交中…”),成功/失败后都必须重置,不能只在then()里写 - 用
AbortController配合fetch(signal)实现超时或手动取消,尤其在离开页面前调abort() - 后端应支持幂等设计(如用
Idempotency-Key请求头),前端生成唯一 key 存 localStorage,提交前检查是否已有相同 key 的 pending 请求
<span class="error"></span>;或者同一表单反复提交,后端没做去重,数据库就多了三条重复记录。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










