我如何处理HTTP GET查询字符串长度限制仍然想要RESTful?

cbl*_*ard 74 rest http

http://www.boutell.com/newfaq/misc/urllength.html中所述,HTTP查询字符串的长度有限.它可能受客户端(Firefox,IE,...),服务器(Apache,IIS,...)或网络设备(应用防火墙......)的限制.

今天我用搜索表单来解决这个问题.我们开发了一个包含很多字段的搜索表单,这个表单作为GET请求发送到服务器,因此我可以将结果页面添加为书签.

我们有很多字段,我们的查询字符串长度为1100字节,我们有一个防火墙可以丢弃超过1024字节的HTTP GET请求.我们的系统管理员建议我们使用POST,这样就没有限制.

当然,POST会起作用,但我真的觉得搜索是一个GET而不是POST.所以我想我会检查我们的字段名称,以确保查询字符串不会太长,如果我不能,我会务实并使用POST.

但RESTful服务的设计是否存在缺陷?如果我们在GET请求中的长度有限,我该如何将大对象发送到RESTful Web服务?例如,如果我有一个基于文件进行计算的程序,我想提供这样的RESTful Web服务:http://compute.com?content=<base64 file>.这不起作用,因为查询字符串不具有无限长度.

我有点不解......

Vin*_*ert 60

HTTP规范实际上建议在将数据发送到资源进行计算时使用POST.

您的搜索看起来像计算,而不是资源本身.如果您仍希望搜索结果成为资源,则可以执行的操作是创建一个标记来标识该特定搜索结果,并将用户代理重定向到该资源.

然后,您可以在一段时间后删除搜索结果标记.

POST /search
query=something&category=c1&category=c2&...

201 Created
Location: /search/01543164876
Run Code Online (Sandbox Code Playgroud)

然后

GET /search/01543164876

200 Ok
... your results here...
Run Code Online (Sandbox Code Playgroud)

这样,浏览器和代理仍然可以缓存搜索结果,但您使用POST提交查询参数.

编辑

为了便于说明,01543164876此处表示代表您的搜索的资源的唯一ID.这两个请求基本上是指:使用这些条件创建新的搜索对象,然后检索与创建的搜索对象关联的结果.

此ID可以是为每个新请求生成的唯一ID.这意味着您的服务器将泄漏"搜索"对象,您将不得不使用缓存策略定期清理它们.

或者它可以是实际表示用户询问的搜索的所有搜索条件的散列.这允许您重用ID,因为重新创建搜索将返回可能(或可能不)已缓存的现有ID.

  • @Rhubarb它通过为给定搜索创建资源来清楚地解决它. (2认同)
  • 这会减慢结果.执行帖子然后执行GET.它将添加至少300ms以获取搜索. (2认同)

jmp*_*pcm 49

根据您的描述,恕我直言,您应该使用POST.POST用于将数据放在服务器上,在某些情况下,可以获得答案.在您的情况下,您进行搜索(向服务器发送查询)并获取该搜索的结果(检索查询结果).

GET的定义说它必须用于检索已经存在的资源.根据定义,POST是创建一个新资源.这正是您正在做的事情:在服务器上创建资源并检索它!即使您不存储搜索结果,您也在服务器上创建了一个对象并将其检索出来.正如PeterMmm previsouly所说,你可以用POST(创建并存储查询结果)然后使用GET来检索查询来执行此操作,但是只做一个POST并检索结果更实际.

希望这可以帮助!:)

  • 这个答案听起来更像是试着玩文字.通过这种逻辑,我们可以将所有内容都设为POST请求,并且仍然是RESTful. (29认同)
  • POST不应该用于搜索,GET是应该使用的,这样你就可以共享和缓存生成的URL和结果,并且你可以更好地利用互联网的RESTful架构 (7认同)
  • 这个答案好像有些律师跟我说:-)问题是"我确实有一个GET案例,好吧.但是我的查询字符串超出了允许的长度.我该如何处理".低估这个答案. (7认同)
  • 你是对的,我可以把它看作一个POST,因为搜索是一个易变的新计算资源.但是我看到POST和GET之间的界限仍然存在问题.如果我想搜索库中的所有科幻小说,我将获得现有资源的集合,所以我很想使用GET,但你建议把它看作一个POST,因为搜索本身就是一个新的资源.因此,GET中的查询字符串应该仅用于更改数据表示,而不能用于过滤数据.我对吗? (2认同)
  • 如果遵循该逻辑,那么每个请求都在创建资源并检索它. (2认同)

小智 6

围绕GET的混淆是浏览器限制.如果要为A2A或P2P应用程序创建RESTful接口,则对GET的长度没有限制.

现在,如果您碰巧想要使用浏览器来查看您的RESTful接口(也就是在开发/调试期间),那么您将遇到这个限制,但是有一些工具可以解决这个问题.

  • “ GET是浏览器限制”-也是服务器限制。您会发现所有Web服务器都实施了限制,如果您有CDN,它们也可能会实施限制。使用其他工具执行请求不会绕过服务器限制。 (4认同)

Pet*_*Mmm 5

REST是一种做事的方式,而不是协议.即使你不喜欢POST,当它真的是GET时,它也会起作用.

如果您将/必须保持GET,POST等的"标准"定义,而不是考虑POST查询,则该查询将存储在具有查询ID的服务器上,并稍后通过ID请求查询.


man*_*ana 5

关于您的示例:http://compute.com?content={base64file},我会使用 POST 因为您正在上传要计算的“东西”。对我来说,这个“东西”感觉更像是作为一个简单参数的资源。

与通常的搜索相反,我会开始坚持使用 GET 和参数。你让 api 客户端更容易测试和使用你的 api。使只读访问(在大多数情况下是大部分流量)尽可能简单!

但是大查询字符串的困境是 GET 的一个有效限制。在这里,我会务实,只要您不达到此限制,请使用 GET 和 url-params。这将适用于 98% 的搜索案例。仅当您达到此限制时才采取行动,然后还将 POST 引入有效负载(使用 mime-type Content-Type: application/x-www-form-urlencoded)。

你有更多真实世界的例子吗?