我怎样才能处理HTTP GET查询string长度的限制,仍然想成为RESTful?

如http://www.boutell.com/newfaq/misc/urllength.html所述 ,HTTP查询string的长度有限。 它可以受到客户端(Firefox,IE,…),服务器(Apache,IIS,…)或networking设备(适用防火墙,…)的限制。

今天我用search表单来面对这个问题。 我们开发了一个带有很多字段的search表单,这个表单被作为一个GET请求发送到服务器,所以我可以为结果页面添加书签。

我们有这么多的字段,我们的查询string是1100字节长,我们有一个防火墙,丢弃超过1024字节的HTTP GET请求。 我们的系统pipe理员build议我们使用POST,所以没有限制。

当然,POST会工作,但我真的感到search作为GET而不是POST。 所以我想我会检查我们的字段名称,以确保查询string不是太长,如果我不能,我会务实和使用POST。

但是在RESTful服务的devise中是否存在缺陷? 如果我们在GET请求中的长度有限,我怎样才能发送大对象到REST风格的web服务? 例如,如果我有一个基于文件进行计算的程序,而且我想提供一个像这样的REST风格的web服务: http://compute.com?content=<base64 file> ://compute.com?content=< http://compute.com?content=<base64 file> 。 这不会工作,因为查询string没有无限长度。

我有点困惑…

根据你的描述,恕我直言,你应该使用POST。 POST是为了将数据放在服务器上,并在某些情况下获得答案。 在你的情况下,你做一个search(发送一个查询到服务器),并得到该search的结果(检索查询结果)。

GET的定义说它必须用来检索已经存在的资源。 根据定义,POST是创build一个新的资源。 这正是你正在做的:在服务器上创build一个资源并检索它! 即使您不存储search结果,您在服务器上创build了一个对象并将其检索出来。 正如PeterMmm预先所说,你可以用POST(创build和存储查询结果)来完成这个工作,然后使用GET来检索查询,但是更实际的做一个POST并检索结果。

希望这可以帮助! 🙂

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

您的search看起来像一个计算,而不是资源本身。 如果您仍然希望将search结果作为资源,则可以执行的操作是创build一个令牌来标识特定search结果并将用户代理redirect到该资源。

然后,您可以在一段时间后删除search结果标记。

 POST /search query=something&category=c1&category=c2&... 201 Created Location: /search/01543164876 

然后

 GET /search/01543164876 200 Ok ... your results here... 

这样,浏览器和代理仍然可以cachingsearch结果,但是您使用POST提交查询参数。

编辑

为了澄清,这里的01543164876表示代表您search的资源的唯一ID。 这2个请求的基本含义是:用这些标准创build一个新的search对象,然后检索与创build的search对象相关联的结果。

此ID可以是为每个新请求生成的唯一ID。 这将意味着你的服务器会泄露“search”对象,你将不得不定期用caching策略来清除它们。

或者它可以是实际上代表用户所要求的search的所有search条件的散列。 这允许您重用ID,因为重新创buildsearch将返回可能(或不可能)已经被caching的现有ID。

REST是一种做事情的方式,而不是协议。 即使你不喜欢POST,但它确实是一个GET,它会工作。

如果您将/必须继续使用GET,POST等的“标准”定义,那么可能会考虑POST一个查询,那么该查询将存储在服务器上,并带有一个查询ID,稍后使用GET请求查询。

GET的困惑是浏览器的限制。 如果您正在为A2A或P2P应用程序创buildRESTful接口,那么对GET的长度没有限制。

现在,如果你碰巧想用浏览器来查看你的RESTful界面(也就是在开发/debugging过程中),那么你将遇到这个限制,但是有一些工具可以解决这个问题。

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

相比之下,在通常的search中,我会开始坚持使用GET和参数。 你可以让api客户端更容易testing和玩你的api。 使只读访问(在大多数情况下是大多数stream量)尽可能简单!

但大查询string的困境是GET的有效限制。 在这里,我会去务实的,只要你不打这个限制去与GET和url-params。 这将在98%的search情况下工作。 只有当你达到这个限制,然后引入有效载荷的POST(使用MIMEtypes的Content-Type: application/x-www-form-urlencoded )时才会起作用。

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

5年后,似乎还有另一个可行的select – 使用GET的消息体。 我将这个答案作为上述所有build议的一个替代scheme,即使它有其自身的局限性(做一些研究)。

这是个简单的。 使用POST。 HTTP对GET的URL长度没有限制,但是服务器是这样做的。 务实一点,用POST来解决这个问题。

你也可以使用一个GET机构(这是允许的),但这是一个双重打击,这是不正确的用法,可能会有服务器问题。