12k
All articles

HTTP 请求中的链接与表单

HTTP 请求中的链接与表单:何时使用 <a>、GET 表单、POST 表单,以及为什么 method=link 在 HTML 中无效。

OpenReplay Team
OpenReplay Team
HTTP 请求中的链接与表单

每当用户点击导航链接或提交搜索查询时,浏览器都会发起一个 HTTP 请求。但触发该请求的 HTML 元素是什么——以及如何触发——比大多数开发者意识到的更重要。在 <a><form> 之间做选择不仅仅是标记偏好,而是一个影响行为、安全性和正确性的语义决策。

核心要点

  • 链接(<a>)用于导航,通常触发 GET 请求。表单(<form>)用于数据提交,同时支持 GET 和 POST。
  • 当用户输入影响 URL 时(如搜索查询)使用 GET 表单,当操作改变服务器状态时(如创建账户)使用 POST 表单。
  • method="link" 是无效的 HTML——浏览器会静默回退到 GET,这可能导致意外行为。
  • HTML 表单原生仅支持 GET 和 POST。对于 PUT、PATCH 或 DELETE,需要使用 JavaScript。

核心区别:HTML 导航 vs 提交

链接(<a>)是导航元素。 它们告诉浏览器:“去获取这个资源。” 点击链接通常会触发一个指向 href 属性中 URL 的 GET 导航请求。就是这样。不收集用户输入,不序列化数据——只是一个纯粹的导航事件。

表单(<form>)是数据提交元素。 它们从用户那里收集输入并将其发送到服务器。表单可以使用 GET 或 POST,具体取决于请求的性质。

以下是快速对比:

特性<a> 链接<form>
用途导航数据提交
HTTP 方法仅 GETGET 或 POST
收集用户输入
右键/在新标签页打开
SEO 可抓取有限
改变服务器状态是(使用 POST)

HTML 表单中的 GET vs POST:各自的应用场景

使用链接进行安全的幂等导航

如果操作不会改变服务器上的任何内容,并且目标可以被收藏或分享,请使用链接:

<a href="/articles/html-basics">阅读 HTML 指南</a>

链接是安全的、幂等的和可缓存的——正是 GET 请求应有的样子。

当用户输入影响 URL 时使用 GET 表单

搜索框是经典示例。用户输入查询,表单将其作为查询字符串附加到 URL:

<form method="get" action="/search">
  <input type="search" name="q" placeholder="搜索...">
  <button type="submit">搜索</button>
</form>

这会生成 /search?q=your+query——一个可分享、可收藏的 URL。当请求仍然是安全且幂等的,但 URL 参数依赖于用户输入时,使用 GET 表单。

当操作有副作用时使用 POST 表单

创建账户、提交支付或发布评论都会改变服务器状态。这些应该使用 POST 表单:

<form method="post" action="/register">
  <input type="email" name="email">
  <input type="password" name="password">
  <button type="submit">创建账户</button>
</form>

POST 在请求体中发送数据,而不是在 URL 中——这适用于敏感数据和非幂等操作。

一些开发者编写 <form method="link"> 希望创建一个”链接按钮”。这是无效的 HTML。浏览器会忽略未知值并回退到默认值——即 GET。表单仍然会提交,但它是静默且错误地进行的。

如果你想要一个导航到某处的按钮,请使用样式化为按钮的链接——而不是表单:

<!-- ❌ 无效 -->
<form method="link" action="/about">
  <input type="submit" value="前往关于页面">
</form>

<!-- ✅ 正确 -->
<a href="/about" class="btn">前往关于页面</a>

值得了解的现代表单功能

HTML5 通过 formactionformmethod 属性添加了按钮级别的覆盖,让单个提交按钮可以改变表单提交的位置或方式:

<form method="post" action="/save">
  <button type="submit">保存</button>
  <button type="submit" formaction="/save-and-publish" formmethod="post">发布</button>
</form>

还值得注意的是:requestSubmit()(与 submit() 不同)在提交前触发表单验证,使其成为 JavaScript 中程序化表单提交的更好选择。

对于 PUT、PATCH 或 DELETE,HTML 表单原生不支持这些方法。你需要使用 JavaScript(fetchXMLHttpRequest)或服务器端方法覆盖约定。

结论

一旦理解了语义,链接和表单之间的选择就很简单了:

  • 导航到页面? 使用链接。
  • 收集用户输入进行查询? 使用 GET 表单。
  • 提交改变服务器状态的数据? 使用 POST 表单。
  • 执行 PUT/PATCH/DELETE? 使用 JavaScript。

选择与操作意图匹配的元素。语义化 HTML 不仅仅关乎正确性——它使你的 UI 可预测、可访问且易于维护。

常见问题

我可以使用 method 为 GET 的表单代替链接进行导航吗?

技术上可以,但这通常是错误的语义选择。GET 表单旨在收集用户输入并将其作为查询参数附加到 URL。对于没有用户输入的简单导航,链接是正确的语义选择。链接可被搜索引擎抓取,支持右键上下文菜单,并向浏览器和辅助技术清晰传达导航意图。

为什么我的 method 为 link 的表单在浏览器中仍然有效?

浏览器将任何无法识别的 method 值视为无效,并静默回退到 GET,这是默认的表单方法。因此 method 为 link 的表单仍会提交,但其行为与 GET 表单完全相同。这可能掩盖错误并产生令人困惑的行为。始终使用 get 或 post 作为表单的 method 值。

JavaScript 中 submit() 和 requestSubmit() 有什么区别?

submit() 方法立即发送表单,不运行内置的 HTML 验证,也不触发 submit 事件。requestSubmit() 方法的行为类似于用户点击提交按钮。它首先触发约束验证并触发 submit 事件,允许事件监听器拦截或取消提交。当需要运行验证时使用 requestSubmit()。

如何从 HTML 页面发送 DELETE 或 PUT 请求?

HTML 表单仅支持 GET 和 POST 作为 method 值。要发送 DELETE、PUT 或 PATCH 请求,你需要使用 fetch 或 XMLHttpRequest 的 JavaScript。一些服务器端框架还支持方法覆盖模式,你可以提交一个 POST 表单,其中包含一个指定预期 HTTP 方法的隐藏输入字段,然后服务器相应地解释它。

Open-source session replay

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.