原生 submit 会跳转,fetch 不会;必须在表单 submit 事件中调用 e.preventdefault() 阻止默认行为,正确使用 formdata(不手动设 content-type),校验 res.ok 处理 http 错误,大文件上传需换 xmlhttprequest 或 readablestream,状态同步需全局管理。

原生 submit 会跳转,fetch 不会——但别以为加了 fetch 就自动生效
只要 <form></form> 存在且用户点了 type="submit" 按钮,浏览器就会走原生提交流程:发请求、跳转页面、丢掉当前 DOM。哪怕你 JS 里写了 fetch,它也根本没机会执行——除非你明确阻止默认行为。
常见错误现象:fetch 调用没报错,但页面还是刷新了;控制台看不到请求发出;后端收不到数据。
- 必须在
submit事件监听器第一行调用e.preventDefault() - 监听器要绑定在表单上,且确保 DOM 已就绪(比如放在
<script></script>底部,或用DOMContentLoaded包裹) - 删掉
<form></form>的action属性,或至少设为空字符串(action=""),避免 preventDefault 失败时意外导航
FormData 提交时手动设 Content-Type 就会失败
当用 new FormData(form) 构造数据并传给 fetch 时,浏览器会自动生成 multipart/form-data 请求体,并附带正确的 boundary。一旦你手动设置 headers: { 'Content-Type': 'multipart/form-data' },这个 boundary 就没了,后端解析直接报错(常见于 PHP 的 $_FILES 为空、Node.js 的 busboy 解析中断)。
- 正确写法:只传
body: formData,完全不配headers - 如果表单不含文件,想发 JSON,那就别用
FormData,改用JSON.stringify()+Content-Type: application/json - 需要带 Cookie 认证?加
credentials: 'include',别碰 headers
fetch 响应处理不校验 status 就容易漏错
fetch 只在网络异常时 reject,HTTP 4xx/5xx 状态码它照常 resolve。这意味着后端返回 400 Bad Request 或 500 Internal Server Error,你的 .then() 还是会进,然后 res.json() 可能失败(因为返回的是 HTML 错误页而非 JSON),或者你拿到空数据却以为成功了。
- 务必检查
if (!res.ok),再决定是否继续解析 - 后端返回非 JSON 内容(比如纯文本、HTML)时,
res.json()会抛错,得用res.text()兜底 - 上传大文件时,
fetch不提供上传进度,别指望onprogress——真要进度就得换XMLHttpRequest或用ReadableStream手动分块
同步一致性真正的难点不在前端,在“状态归属”
表单提交后,页面要不要更新?更新哪块?DOM 是立刻清空,还是保留输入、仅刷新结果区?这些不是技术问题,而是业务逻辑问题。比如用户填完注册表单,fetch 成功后你是跳转到欢迎页,还是就地显示“注册成功”,同时禁用按钮、清空字段?
最容易被忽略的点:多个表单共用同一份后端数据源时,一个表单提交成功,其他页面或组件里的对应数据显示没同步。这不是 fetch 能解决的——得靠全局状态管理(如 localStorage 更新触发事件)、WebSocket 广播,或者干脆让所有读取方重新 fetch 一次最新数据。否则,你防住了刷新,却没防住视图滞后。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











