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

Posted

技术标签:

【中文标题】在搜索表单中发布或获取?【英文标题】:POST or GET in a search form? 【发布时间】:2013-12-31 06:40:29 【问题描述】:

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

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

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

使用 GET 有什么缺点吗?

谢谢你, 米格尔

【问题讨论】:

***.com/questions/195212/… 【参考方案1】:

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

HTTP 协议没有对 a 的长度设置任何先验限制 URI。服务器必须能够处理它们所使用的任何资源的 URI 服务,并且应该能够处理无限长度的 URI,如果它们 提供可以生成此类 URI 的基于 GET 的表单。服务器应该 如果 URI 长于 服务器可以处理(参见第 10.4.15 节)。

但正如 Jasen 评论,浏览器可以有限制。

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

【讨论】:

我没有修改任何数据,这就是我想使用 GET 的原因。我是否需要对输入中插入的内容进行任何保护?基本上,我通过获取最多 4 个长度高于 4 个字符的不同单词来解析字符串。然后我在数据库中搜索标题中包含该词的帖子。 我正在使用实体框架...在此之前,我拆分所有单词并获得一些满足我的标准的单词,因此即使有某种脚本,它也会在那个阶段被销毁...我认为 浏览器有查询字符串限制。 ***.com/questions/812925/… 感谢 Jasen 的提示,我已在我的 anwser 中添加。 对于任何使用 POST 实现搜索结果的人,请竖起中指。回到搜索结果是一件事情,而 POST 打破了平滑的返回行为。我认为绝对没有理由将 POST 用于搜索结果。【参考方案2】:

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

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

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

语义到底有多重要?我们是否应该遵循可能导致技术债务的变通办法,只是为了遵守命名约定?

问题案例示例

如上所述,其中一个可能的问题是无法处理数组

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

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

解决方法 1

您只需使用查询参数,就可以将其建模为一组布尔值:includeVendorAincludeVendorB、...

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

解决方法 2

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

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

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

解决方法 3

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

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

终于

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

2021 年更新

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

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

【讨论】:

【参考方案3】:

搜索不一定是帖子,您是在尝试获取一些数据,而不是修改或插入。

【讨论】:

我没有修改任何数据,这就是我想使用 GET 的原因。我是否需要对输入中插入的内容进行任何保护?基本上,我通过获取最多 4 个长度高于 4 个字符的不同单词来解析字符串。然后我在数据库中搜索标题中包含该词的帖子。 您可以使用其他技术来处理它,例如在 sql 或存储过程中使用参数,使用 linq 之类的东西等。【参考方案4】:

除非您要修改数据,否则我会使用 GET。如果您总是获取数据而不是操作数据,我认为没有任何缺点。

【讨论】:

以上是关于在搜索表单中发布或获取?的主要内容,如果未能解决你的问题,请参考以下文章

从一个表单字段获取条目并在数据库中搜索其对应数据并自动填写表单中的其他字段

创建一个搜索表单,该表单将从用户那里获取输入并显示视频弹出窗口

重新查询或刷新无法更新打开表单上的子表单

发送数据并提交表单到不同的网站并获得结果

使用带有 Python Flask 的 HTML 表单搜索 MongoDB 集合

Laravel:高级搜索表单查询