formaction 属性允许同一表单内多个提交按钮指向不同 URL,天然支持“保存并预览”和“直接发布”等多操作场景;配合 formmethod 可分别指定 GET 预览与 POST 发布,后端按路径路由即可区分处理,语义清晰且无需 JavaScript。

HTML5 中的 formaction 属性可以为同一个表单内的不同提交按钮指定独立的提交地址,从而天然支持“保存并预览”和“直接发布”这类多操作场景,无需 JavaScript 也能实现语义清晰、后端可区分的请求分发。
用 formaction 区分两种提交行为
在同一个 <form> 内,给不同按钮设置不同的 formaction 值,浏览器会忽略表单本身的 action,改用点击按钮上定义的 URL 提交数据:
<button type="submit" formaction="/api/preview">保存并预览</button><button type="submit" formaction="/api/publish">直接发布</button>
两个按钮共用同一组表单字段(如标题、正文、分类等),但提交目标不同,后端可分别处理:预览接口只校验+渲染 HTML 预览页,发布接口则完成持久化并上线。
配合 method 和 formmethod 精确控制请求方式
如果预览需要 GET(便于调试、可缓存),而发布必须 POST(含敏感操作),可进一步用 formmethod 显式声明:
立即学习“前端免费学习笔记(深入)”;
<button type="submit" formaction="/preview" formmethod="get">预览</button><button type="submit" formaction="/publish" formmethod="post">发布</button>
注意:GET 请求会把所有表单字段拼成查询参数,适合轻量预览;POST 更安全,也支持大文本或文件上传。
服务端如何识别和响应
后端无需额外解析按钮名称,仅需根据请求路径(如 /preview 或 /publish)路由到对应逻辑即可。例如在 Express 中:
app.post('/publish', handlePublish)app.get('/preview', handlePreview)
若需兼容旧浏览器(如 IE),可退化为统一提交至一个 endpoint,再通过按钮的 name 和 value 辅助判断(如 <button name="action" value="preview">),但原生 formaction 更简洁可靠。
避免常见陷阱
确保所有按钮都明确写 type="submit"(否则可能不触发提交);不要在按钮上同时写 formaction 和 onclick 干扰默认行为;预览接口返回的 HTML 应包含原始表单数据(如用 hidden 字段回传),方便用户修改后再次提交。



















