使用 POST 作为 URL 字符限制的解决方法
Posted
技术标签:
【中文标题】使用 POST 作为 URL 字符限制的解决方法【英文标题】:Using POST as a workaround for the URL character limit 【发布时间】:2011-08-22 06:56:59 【问题描述】:如果你有一个API,仅仅因为URL长度限制和请求中传递复杂的参数而支持POST操作,你还能说你有RESTful架构吗?
以上基本上暗示的是,对于这个特定的(只读)API,GET 和 POST 之间没有语义差异,所以可以用 GET 完成的操作也可以用 POST 完成(但不是反之亦然,由于限制)。
这仍然会使架构的风格成为 RESTful 风格吗?
【问题讨论】:
【参考方案1】:从技术上讲,您没有违反任何约束。但是,您正在严重减少请求的自我描述性。这将导致失去缓存响应的能力。能够缓存响应是构建有效 REST 系统所需的基本功能。
【讨论】:
+1 这是很重要的一点。我还建议,如果您遇到 URL 字符限制,最好检查您的 URL 方案,看看是否有重构的机会。可能有太多的查询选项,就像你可以有太多的函数或方法参数一样。【参考方案2】:您肯定会失去 HTTP 为 GET 请求提供的功能。例如,代理对 GET 请求做出某些假设(幂等性、可缓存性)。
POST 本身没有什么问题,但也许 REPORT 方法更合适。
【讨论】:
报告?这不是 HTTP 方法。 @Darren Miller:这不是标准方法,不。但是 HTTP 规范允许自定义方法。 是的,它是一个扩展;就像 PATCH 和许多其他人一样。确实在 HTTP 规范中必须允许扩展。我相信这是 HTTP/1.1 的目标之一。 @jgauffin 如果您准备通过 IETF 推动新的公共规范,HTTP 规范允许扩展。 PATCH 花了数年时间才获得批准http://tools.ietf.org/html/rfc5789
你“必须”不仅仅是自己编造的。
报告未编造。请参阅:tools.ietf.org/html/draft-ietf-httpbis-method-registrations-05。从 2002 年开始,它出现在几个 HTTP 扩展中。【参考方案3】:
所以这里的问题是关于restful架构而不是restful web services。如果我们按照Wiki-RestfulArch-Constraints上提供的信息,是的。
【讨论】:
【参考方案4】:Roy Fielding 于 2000 年在他的博士论文中引入并定义了 Representational State Transfer 一词。第 6.3 节解释了如何将 REST 应用于 HTTP:http://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_3
Fielding 并未声称禁止使用 POST。
***还提到 POST 作为 RESTful Web 服务的合法 HTTP 操作: http://en.wikipedia.org/wiki/Representational_State_Transfer#RESTful_web_services
【讨论】:
对所有内容使用 GET 违反了 HTTP 标准,该标准明确规定 GET 只能用于未被修改的资源。引用自 RFC:the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval
。尊重该声明非常重要。
jgauffin 没有人在谈论使用 GET 进行不安全操作,他们在谈论使用 POST 进行安全操作!
@jgauffin 当然 POST 是允许的。这也不是问题。问题是您能否将 POST 用于通常是 GET 的事情。即安全和幂等的请求。答案是可以,但这不是一个好主意。
在他编辑他的答案之前,我只是更正了ceving。我遇到了很多想要对所有调用都使用 GET 的开发人员。至于问题:当我评论(不正确的)答案时,问题所说的并不相关。【参考方案5】:
为什么不直接切换到在 GET 中包含正文而不是使用查询字符串?
更新
RFC 说明如下:
服务器应该 根据任何请求阅读和转发消息正文;如果请求方法 不包括实体主体的定义语义,则 处理请求时应该忽略消息体
规范中没有任何内容 规定不能将主体包含在任何方法中。并且所有代理、服务器等都必须包含正文。是否忽略正文取决于处理程序(您)。
对于 GET 方法,没有任何说明它不能包含正文。
这意味着只要您的网络服务器支持,您就可以使用 GET 正文。
【讨论】:
因为 HTTP 规范说 GET 正文没有任何意义,并且可能被服务器或中介拒绝。 这是个坏主意;即使您的 http 堆栈应该支持它,但我怀疑它们是否真的支持。基于 GET 中的请求正文,“内容否定”也没有语义。 (尽管从技术上讲这不是内容协商,但你不能改变:主体.. 基本上)。 你是对的。我刚刚尝试在 .NET 中使用HttpListener
和 HttpWebRequest
,但没有成功。
当您参考规范时,最好包含一个链接http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-14#section-7.3
“GET 请求上的正文没有定义的语义。请注意,在 GET 请求上发送正文可能会导致某些现有实现拒绝请求。”
在 RFC 的“SHOULD”中有非常精确的含义。将其改写为“有义务”并没有真正的帮助。除非规范说“必须”,否则您必须处理未遵守规则的情况。以上是关于使用 POST 作为 URL 字符限制的解决方法的主要内容,如果未能解决你的问题,请参考以下文章