formaction属性会完全忽略form的action,直接以按钮自身的formaction值为准发起提交;仅对type="submit"的button或input有效,且优先级最高。

formaction 覆盖 action 的优先级规则
formaction 不是“增强”或“补充”表单提交行为,而是**直接拦截并替换**当前按钮触发时的提交目标。只要点击带 formaction 的 <button type="submit"></button> 或 <input type="submit">,浏览器就会完全忽略 <form></form> 标签上的 action 属性,哪怕它写得再完整、再绝对。
这个覆盖是单次、即时、无状态的:不修改表单本身,也不影响其他按钮。你甚至可以给五个按钮分别设五个 formaction,它们互不干扰。
常见错误现象:
– 表单写了 action="/api/default",但某个按钮始终提交到这个地址,检查发现该按钮漏了 type="submit"(比如写成 type="button");
– 按钮写了 formaction="/save",却仍跳转到首页,大概率是拼错了属性名(如写成 action 或 form-action);
– 后端收不到数据,可能是没配 formmethod,而表单默认是 GET,但接口只接受 POST。
多个按钮共存时的参数与编码继承逻辑
formaction 只改 URL,其余提交行为(方法、编码类型、目标窗口)默认继承自 <form></form>。这意味着:
- 如果
<form method="post" enctype="multipart/form-data"></form>,所有带formaction的按钮默认也走POST+multipart/form-data - 若某个按钮需要不同行为(例如上传附件用
POST,预览用GET),必须显式加formmethod="get"或formenctype="application/x-www-form-urlencoded" -
formtarget同理:不写就继承form的target(通常是_self),要新窗口打开就得写formtarget="_blank"
典型场景示例:<button type="submit" formaction="/api/preview" formmethod="get">预览</button><button type="submit" formaction="/api/upload" formmethod="post" formenctype="multipart/form-data">上传附件</button>
IE 和旧版 Safari 的 fallback 兼容方案
IE 完全不支持 formaction,Safari 12 及更早版本对 formmethod 和 formenctype 支持不稳定。纯靠 HTML5 原生属性无法兜底。
可行的轻量兼容策略是:保留原生结构,用极简 JS 拦截并修正提交行为,而不是重写整个提交逻辑:
- 给每个按钮加唯一
data-action和data-method属性,如<button data-action="/api/draft" data-method="post">保存草稿</button> - 监听表单
submit事件,通过event.submitter拿到被点击的按钮,读取其dataset.action并赋给form.action和form.method - 仅在检测到不支持
formaction的 UA 时才启用这段 JS(避免现代浏览器多执行一次赋值)
注意:不要用 form.setAttribute('action', ...),应直接赋值 form.action = ...,否则部分旧浏览器可能不触发更新。
容易被忽略的 base 标签冲突
如果页面中存在 <base href="https://cdn.example.com/">,那么所有相对路径的 formaction(如 formaction="/api/save")都会被解析为 https://cdn.example.com/api/save——这不是 bug,是规范行为,但几乎总是错的。
验证方式很简单:
– 打开开发者工具 → Elements 面板 → 搜索 <base>
<br>– 或控制台执行 <code>document.querySelector('base')?.href
解决办法只有两个:
– 把 formaction 改成绝对 URL(如 formaction="https://your-api.com/api/save")
– 或移除 <base>,改用其他方式处理资源路径(比如 webpack 的 public 目录或 CDN 前缀配置)
这个坑不会报错,只会静默发请求到错误域名,后端收不到、前端看不到 network 请求失败(因为跨域被拦在预检阶段或直接 404),排查成本极高。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











