formmethod属性仅对type="submit"或type="image"按钮生效,用于覆盖表单method,值为小写get/post,需在<form>内或通过form="id"关联,且不能被JavaScript阻止默认行为。

formmethod 属性只对 submit 类型按钮生效
直接在 <input> 或 <button> 上设置 formmethod="post" 仅当它的 type="submit" 时才起作用。如果写成 type="button" 或没写 type,默认是 type="submit",但很多开发者误以为加了 formmethod 就能“局部覆盖”,结果发现请求仍是 GET —— 很可能是因为按钮没绑定到表单,或表单本身有 method="get" 且按钮没显式声明 formmethod。
实操要点:
- 确保按钮是表单内元素,或通过
form="form-id"显式关联到目标<form> - 必须写
type="submit"(哪怕你没写,浏览器也默认为 submit,但显式写出更安全) -
formmethod只影响该按钮触发的提交行为,不影响其他 submit 按钮或表单默认 method - 若按钮在表单外,必须配
form="xxx",否则formmethod完全无效
常见错误:点击后仍是 GET 请求
典型现象是:表单 <form method="get">,里面一个按钮写了 <button type="submit" formmethod="post">提交</button>,但 Network 面板里看到的仍是 GET 请求。原因通常是:
- 按钮没在
<form>标签内部,也没用form="id"关联 - 按钮用了
type="button"(此时它不触发表单提交,formmethod被忽略) - 表单设置了
onsubmit="return false"或 JS 阻止了默认行为,但没手动调用fetch或XMLHttpRequest,导致实际没发请求 - 浏览器兼容性问题:IE 不支持
formmethod,Edge 12+、Chrome 27+、Firefox 20+ 才支持
对比 formmethod 和 JavaScript 手动提交
用 formmethod 是语义化、零 JS 的方案,适合简单场景;但一旦需要控制请求头、处理响应、防重复提交,就得切到 JS。两者不互斥,但别混用:
立即学习“前端免费学习笔记(深入)”;
-
formmethod="post"提交会刷新页面(除非表单有target="_blank"或 action 指向 iframe) - JS 提交(如
fetch())可避免跳转,但要自己序列化表单数据(new FormData(form))、处理错误、更新 UI - 如果同时写了
formmethod="post"和form.onsubmit = e => { e.preventDefault(); ... },前者被完全绕过 -
formmethod不影响enctype,如需multipart/form-data,得配formenctype="multipart/form-data"
完整可运行示例
<form id="search-form" action="/search"> <input name="q" value="test"> <!-- 默认按 form 的 method="get" 提交 --> <button type="submit">GET 搜索</button> </form> <p><!-- 局部改为 POST,且关联到上面的 form --> <button type="submit" form="search-form" formmethod="post" formaction="/api/submit"> POST 提交 </button>
注意:formaction 可选,不写则仍走 <form> 的 action;formmethod 必须和 type="submit" 同时存在才有效;两个按钮提交的 endpoint 和 method 完全独立。
真正容易被忽略的是:这个机制依赖浏览器原生表单提交逻辑,一旦加了 e.preventDefault(),所有 form* 属性都失效 —— 这时候就得老老实实用 JS 控制了。



















