协慌网

登录 贡献 社区

如何在 HTTP POST 请求中发送参数?

在 HTTP GET请求中,参数作为查询字符串发送:

http://example.com/page ?parameter=value&also=another

在 HTTP POST请求中,参数不会与 URI 一起发送。

价值在哪里?在请求标题中?在请求机构?它是什么样子的?

答案

值以请求正文中的内容类型指定的格式发送。

通常内容类型是application/x-www-form-urlencoded ,因此请求正文使用与查询字符串相同的格式:

parameter=value&also=another

当您在表单中使用文件上载时,您可以使用multipart/form-data编码,它具有不同的格式。它更复杂,但你通常不需要关心它的样子,所以我不会展示一个例子,但知道它存在是很好的。

内容放在 HTTP 标头之后。 HTTP POST 的格式是具有 HTTP 标头,后跟空行,后跟请求主体。 POST 变量作为键值对存储在正文中。

您可以在 HTTP Post 的原始内容中看到这一点,如下所示:

POST /path/script.cgi HTTP/1.0
From: frog@jmarshall.com
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32

home=Cosby&favorite+flavor=flies

您可以使用像Fiddler这样的工具来查看它,您可以使用它来查看通过网络发送的原始 HTTP 请求和响应有效负载。

简答:在 POST 请求中,值在请求的 “正文” 中发送。对于网络表单,他们很可能使用媒体类型的application/x-www-form-urlencodedmultipart/form-data 。设计用于处理 Web 请求的编程语言或框架通常使用此类请求执行 “正确的 Thing™”,并为您提供对易于解码的值的轻松访问(例如 PHP 中的$_REQUEST$_POST ,或cgi.FieldStorage() ,在 Python 中使用flask.request.form )。


现在让我们稍微离题,这可能有助于理解差异;)

GETPOST请求之间的区别主要是语义上的。它们也被 “使用” 不同,这解释了值的传递方式的差异。

GET( 相关 RFC 部分

执行GET请求时,您向服务器询问一个或一组实体。要允许客户端过滤结果,它可以使用 URL 的所谓 “查询字符串”。查询字符串是后面的部分? 。这是URI 语法的一部分。

因此,从应用程序代码( 接收请求的部分)的角度来看,您需要检查 URI 查询部分以获取对这些值的访问权限。

请注意,键和值是 URI 的一部分。浏览器可能会对 URI 长度施加限制。 HTTP 标准规定没有限制。但在撰写本文时,大多数浏览器确实限制了 URI(我没有特定的值)。 绝不应使用GET请求向服务器提交新信息。特别是不大的文件。这就是你应该使用POSTPUT

POST( 相关 RFC 部分

执行POST请求时,客户端实际上是在向远程主机提交新文档 。因此, 查询字符串(语义上)没有意义。这就是您无法在应用程序代码中访问它们的原因。

POST是更复杂的(和方式更灵活)一点点:

收到 POST 请求时,您应该总是期望 “有效负载”,或者在 HTTP 术语中: 消息体 。消息体本身是没用的,因为没有标准 (据我所知。也许是 application / octet-stream?)格式。正文格式由Content-Type标头定义。使用带有method="POST"的 HTML FORM元素时,通常是application/x-www-form-urlencoded 。如果您使用文件上传,另一种非常常见的类型是multipart / form-data 。但是可能是任何东西 ,从text/plainapplication/json甚至是自定义application/octet-stream

在任何情况下,如果POST请求是使用应用程序无法处理的Content-Type ,则应返回415状态代码

大多数编程语言(和 / 或 Web 框架)提供了一种从最常见的类型(对于application/x-www-form-urlencodedmultipart/form-dataapplication/json )对消息体进行解码 / 编码的方法。 。这很容易。自定义类型可能需要更多工作。

使用标准 HTML 表单编码文档作为示例,应用程序应执行以下步骤:

  1. 阅读Content-Type字段
  2. 如果该值不是受支持的媒体类型之一,则返回具有415状态代码的响应
  3. 否则,解码消息正文中的值。

同样,PHP 等语言或其他流行语言的 Web 框架可能会为您处理此问题。例外是415错误。没有框架可以预测应用程序选择支持和 / 或不支持的内容类型。这取决于你。

PUT( 相关 RFC 部分

PUT请求的处理方式与POST请求完全相同。最大的区别是POST请求应该让服务器决定如何创建新资源(如果有的话)。从历史上看(从现在过时的 RFC2616 开始,创建一个新资源作为发送请求的 URI 的 “从属”(子))。

PUT相反请求应该 “存款” 的资源恰好该 URI,并用确切该内容。不多也不少。这个想法是客户负责在 “PUT” 之前制作完整的资源。服务器应该在给定的 URL 上按原样接受它。

因此, POST请求通常不用于替换现有资源。 PUT请求可以同时创建替换。

边注

还有 “ 路径参数 ” 可用于向遥控器发送附加数据,但它们非常罕见,我不会在这里详细介绍。但是,作为参考,这里是 RFC 的摘录:

除了分层路径中的点段之外,通用语法将路径段视为不透明。 URI 生成应用程序通常使用段中允许的保留字符来分隔特定于方案或解除引用处理程序的子组件。例如,分号(“;”)和等于(“=”)保留字符通常用于分隔适用于该段的参数和参数值。逗号(“,”)保留字符通常用于类似目的。例如,一个 URI 生成器可能使用诸如 “name; v = 1.1” 之类的段来表示对 “name” 的版本 1.1 的引用,而另一个 URI 生成器可能使用诸如 “name,1.1” 之类的段来表示相同。参数类型可以由特定于方案的语义定义,但是在大多数情况下,参数的语法特定于 URI 解除引用算法的实现。