在搜索表单中发布或获取?

Mig*_*ura 3 .net rest asp.net-mvc http

我创建了一个搜索表单来查找 MVC 站点上的帖子。

表单类型应该是 POST 还是 GET?

我知道 get 可以为搜索添加书签等等。

使用 GET 有什么缺点吗?

谢谢你,米格尔

Fel*_*ani 10

对于GET动词,参数将在 上URL,没有 http 请求正文GET。使用POST可能不是合适的解决方案,如果我们在 URL 上也有参数,但我们可以以特定格式(json、xml、文本等)将更多数据发送到请求正文中。正如动词名称所说,使用GET是最好的解决方案,您还可以获得复制/粘贴此网址并在任何地方共享的好处。http URL 的参数没有限制。

HTTP 协议对 URI 的长度没有任何先验的限制。服务器必须能够处理它们所服务的任何资源的 URI,并且如果它们提供可以生成此类 URI 的基于 GET 的表单,则应该能够处理无限长度的 URI。如果 URI 长于服务器可以处理的长度,服务器应该返回 414(请求 URI 太长)状态(请参阅第 10.4.15 节)。

但正如 Jasen 评论的那样,浏览器可能有限制。

无论如何,请记住使用避免方法sql injection。如果您要使用ado.net,请使用Parameters. 如果您正在使用,ORM它会照顾您。


bvd*_*vdb 6

尽管GET是用于查询数据的更传统的解决方案,但在很多情况下 aGET太有限而无法执行 a /search

问题的本质是aGET没有 request body,因此它无法处理更复杂的请求。本质上 aGET只能使用 URL 发送数据。URL 可以包含路径参数和查询参数,它们只是一组键值对,其中键和值都是一种string类型。

相比之下,aPOST还可以在其主体中携带整个 JSON 文档。通过将自己限制在 a GET我们无法使用任何这些 JSON 功能,因此我们无法将正确的对象或数组发送到我们的后端。

语义到底有多大价值?我们是否应该遵循可能导致技术债务的解决方法,只是为了遵守命名约定?

问题案例示例

如上所述,可能出现的问题之一是它无法处理数组

例如,在网上商店中,您希望用户展示以列表形式展示的产品目录。您希望让您的用户能够使用复选框过滤列表来选择多个供应商。它会产生一个数组,例如selectedVendors = ["vendorA", "vendorB"].

如果我们想遵守使用 a 的约定GET,那么我们必须找到一种可接受的解决方法,允许我们在不使用请求正文的情况下将供应商列表发送到后端。

解决方法 1

只有查询参数可供您使用,可以将其建模为一堆布尔值:includeVendorA, includeVendorB, ...

不幸的是,这很难维护且难以记录。

解决方法 2

前端实际上可以执行多个查询。IE

  • 首先获取 vendorA ( /search?vendor=VendorA)的那些,
  • 然后是 vendorB ( /search?vendor=VendorB)
  • 然后最后将所有结果合并回一个列表。

首先,它有性能损失,因为它需要多次往返。但其次,它也打破了支持分页的能力。

解决方法 3

将增量索引添加到您的查询参数名称。(例如/search?vendor1=VendorA&vendor2=VendorB

同样,难以记录,OpenAPI 也不支持。

最后

如果我们可以接受 aPOST更适合 a /search,那么我们不需要任何这些变通方法。

2021 年更新

专门用于通过 发送数组GET,目前还没有一个标准。然而,框架和语言正在慢慢转向事实上的标准:/search?vendor[]=VendorA&vendor[]=VendorB.

, 的一个更具体的缺点GET是能够对条件过滤器进行建模:(例如,在票务系统中:“给我 X 创建的所有票和 X 关闭的所有票”,或在网上商店:“给我所有打折产品和所有免费送货的产品”)。它们转换为混合了ANDOR语句的数据库查询。