当前位置:  开发笔记 > 编程语言 > 正文

带有URL查询参数的HTTP POST - 好主意与否?

如何解决《带有URL查询参数的HTTPPOST-好主意与否?》经验,为你挑选了5个好方法。

我正在设计一个API来通过HTTP,我想知道是否使用HTTP POST命令,但只使用URL查询参数而没有请求体,是一个很好的方法.

注意事项:

"良好的网页设计"要求通过POST发送非幂等操作.这是一种非幂等行为.

当URL中存在请求参数时,更容易开发和调试此应用程序.

该API不适合广泛使用.

似乎在没有正文的情况下发出POST请求会花费更多的工作,例如Content-Length: 0必须明确添加标头.

在我看来,没有正文的POST与大多数开发人员和HTTP框架的期望有点相反.

通过URL查询而不是请求体在POST请求上发送参数是否还有其他缺陷或优势?

编辑:正在考虑的原因是操作不是幂等的,并且除了检索之外还有副作用.请参阅HTTP规范:

特别是,已经建立了这样的惯例:GET和HEAD方法不应该具有采取除检索之外的动作的重要性.这些方法应该被认为是"安全的".这允许用户代理以特殊方式表示其他方法,例如POST,PUT和DELETE,以便使用户意识到正在请求可能不安全的操作.

...

方法也可以具有"幂等"的属性(除了错误或到期问题)N> 0个相同请求的副作用与单个请求相同.方法GET,HEAD,PUT和DELETE共享此属性.此外,方法OPTIONS和TRACE不应该有副作用,因此本质上是幂等的.

Don McCaughe.. 246

如果你的行为不是幂等的,那么你必须使用POST.如果你不这样做,那你只是在寻找麻烦. GET,PUTDELETE被方法需要为幂等.想象一下,如果客户端预先提取GET您的服务的每个可能请求,您的应用程序会发生什么- 如果这会导致客户端可见的副作用,那么就会出错.

我同意发送POST带有查询字符串但没有正文的字符似乎很奇怪,但我认为它在某些情况下是合适的.

可以将URL的查询部分视为资源的命令,以限制当前请求的范围.通常,查询字符串用于对GET请求进行排序或过滤(例如?page=1&sort=title),但我认为在a POST上也有意义也限制了范围(也许是这样?action=delete&id=5).



1> Don McCaughe..:

如果你的行为不是幂等的,那么你必须使用POST.如果你不这样做,那你只是在寻找麻烦. GET,PUTDELETE被方法需要为幂等.想象一下,如果客户端预先提取GET您的服务的每个可能请求,您的应用程序会发生什么- 如果这会导致客户端可见的副作用,那么就会出错.

我同意发送POST带有查询字符串但没有正文的字符似乎很奇怪,但我认为它在某些情况下是合适的.

可以将URL的查询部分视为资源的命令,以限制当前请求的范围.通常,查询字符串用于对GET请求进行排序或过滤(例如?page=1&sort=title),但我认为在a POST上也有意义也限制了范围(也许是这样?action=delete&id=5).


我为这个特殊情况选择了这个答案,但我认为R. Bemrose的论点对公共API很有说服力.
我不认为他的答案是完全正确的.如果您在将HTML页面发送到客户端时知道表单帖子的URL参数,则可以将这些URL参数添加到表单的action属性,否则JavaScript可以在提交表单时设置URL参数.
如何将xml文件的帖子发送到带有查询参数的url?那可能吗?
另一个例子:请求数据可以在http实体中,而请求的响应格式在查询参数中传递(`/ action?response_format = json`)
+1今天学到了一些东西 删除具有幂等的技术性.如果对象实际被删除,那么您将得到一个未找到的404,因此服务器将具有相同的状态,但响应将是不同的.见牛图片:http://www.restapitutorial.com/lessons/idempotency.html

2> Tim Lovell-S..:

每个人都是对的:坚持使用POST来处理非幂等请求.

如何同时使用URI查询字符串和请求内容?那么它是有效的HTTP(见注1),为什么不呢!

它也是完全合乎逻辑的:URL,包括它们的查询字符串部分,用于定位资源.而HTTP方法谓词(POST - 及其可选的请求内容)用于指定操作或如何处理资源.那些应该是正交问题.(但是,对于ContentType = application/x-www-form-urlencoded的特殊情况,它们并不是完美正交的问题,请参阅下面的注释2.)

注1:HTTP规范(1.1)没有规定查询参数和内容对接受POST或PUT请求的HTTP服务器是互斥的.所以任何服务器都可以自由接受.即如果你编写服务器,没有什么可以阻止你选择接受两者(除了可能是一个不灵活的框架).通常,服务器可以根据它想要的任何规则来解释查询字符串.它甚至可以用引用其他标题的条件逻辑来解释它们,例如Content-Type,这导致注2:

注意2:如果Web浏览器是人们访问您的Web应用程序的主要方式,并且application/x-www-form-urlencoded是他们发布的Content-Type,那么您应该遵循该Content-Type的规则.application/x-www-form-urlencoded的规则更具体(坦率地说,不常见):在这种情况下,您必须将URI解释为一组参数,而不是资源位置.[这与Powerlord提出的有用点相同; 可能很难使用Web表单将内容POST到您的服务器.刚才解释得有点不同.]

注3:最初的查询字符串是什么?RFC 3986将HTTP查询字符串定义为URI部分,作为定位资源的非分层方式.

如果读者提出这个问题希望问什么是好的RESTful架构:RESTful架构模式不需要URI方案以特定的方式工作.RESTful架构关注系统的其他属性,如资源的可缓存性,资源本身的设计(它们的行为,功能和表示),以及是否满足幂等性.或者换句话说,实现与HTTP协议及其HTTP方法动词集高度兼容的设计.:-)(换句话说,RESTful架构对资源的定位并不是非常有用.)

最后注意事项:有时查询参数会用于其他事情,既不是资源定位也不是编码内容.曾经见过像'PUT = true'或'POST = true'这样的查询参数?这些是不允许您使用PUT和POST方法的浏览器的变通方法.虽然这些参数被视为URL查询字符串的一部分(在线上),但我认为它们不是精神上 URL查询的一部分.



3> Powerlord..:

你想要理由吗?这是一个:

Web表单不能用于向使用GET和POST混合的页面发送请求.如果将表单的方法设置为GET,则所有参数都在查询字符串中.如果将表单的方法设置为POST,则所有参数都在请求正文中.

资料来源:HTML 4.01标准,第17.13节表格提交


是的,但method属性只定义了"表单数据集"如何包含在请求中.当`method`是POST时,没有提到在表单的`action`中更改URI.并且任何URI当然都可以包含查询字符串部分.
@Powerlord这是错的.尝试使用例如的操作将表单设置为POST.`/书籍?的bookcode = 1234`.Web服务器将获得POST表单变量和查询字符串.
这是一个不错的论点,但我认为现代浏览器的Javascript实现有点让人讨厌.不过我会考虑它 - 它以未来的方式引人注目.仅仅因为我现在没有使用表格并不意味着我不想在以后.
将GET与POST混合只是一个非常糟糕的主意 - 非常破坏HTTP并且没有充分的理由.
该代码段不会出现在您链接的页面上
downvote,已经由@Gareth和@Powerlord解释的原因......`
`````
@Gareth:它隐含在方法属性的描述中.您只能将其设置为*或*post,而不是两者.
顺便说一句,我也认为不可能混合使用GET和POST.我在规范中找不到任何理由,我认为你的解释与那里写的不符
@Jez:可能完全取决于浏览器,考虑到HTML4没有说这样做.我没有看过HTML5在这个问题上所说的内容,但请记住,这个答案是在大约4年前编写的,HTML5仅在几个月前完成.

4> jro..:

从程序化的角度来看,对于客户端来说,它打包参数并将它们附加到URL并进行POST与GET.在服务器端,它正在从查询字符串而不是发布的字节中评估入站参数.基本上,这是一个洗.

可能存在优点/缺点的可能是特定客户端平台如何在其网络堆栈中使用POST和GET例程,以及Web服务器如何处理这些请求.根据您的实现,一种方法可能比另一种方法更有效.知道这将指导您的决定.

尽管如此,从程序员的角度来看,我更喜欢允许在主体中使用所有参数的POST,或者在URL上使用所有参数的GET,并使用任何POST请求明确忽略url参数.它避免了混淆.



5> 小智..:

我认为让查询参数标识URL上的资源,同时将内容有效负载限制在POST正文中,可能仍然非常RESTful。这似乎将“我要发送什么?”的考虑分开。而不是“我要寄给谁?”。


问题不是关于REST。
@ user359996并非所有的HTTP API都是RESTful的。实际上,大多数声称实际上不是的API。同样,有趣的是,REST也不是仅HTTP。
推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有