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

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

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

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

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

这些值以内容types指定的格式在请求正文中发送。

通常内容types是application/x-www-form-urlencoded ,所以请求主体使用与查询string相同的格式:

 parameter=value&also=another 

当您在表单中使用文件上载时,您将使用multipart/form-data编码,而不是格式。 这是比较复杂的,但是你通常不需要关心它是什么样的,所以我不会示例,但是知道它是存在的就可以。

内容放在HTTP头之后。 HTTP POST的格式是有HTTP头,后跟一个空行,后跟请求主体。 POSTvariables作为键值对存储在主体中。

您可以在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请求中,值是在请求的“主体”中发送的。 通过networking表单,他们很可能是通过媒体types的application/x-www-form-urlencodedmultipart/form-data 。 编程语言或框架已被devise为处理networking请求通常做“正确的事情™”与这样的要求,并为您提供轻松获取解码值(如$_REQUEST$_POST在PHP中,或cgi.FieldStorage() ,Python中的flask.request.form )。


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

GETPOST请求之间的区别在很大程度上是语义上的。 它们也被“使用”了,这就解释了值如何传递的不同。

GET( 相关RFC部分 )

执行GET请求时,请求服务器提供一个或一组实体。 为了让客户过滤结果,可以使用URL的所谓的“查询string”。 查询string是? 。 这是URI语法的一部分。

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

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

POST( 相关RFC部分 )

当执行POST请求时,客户端实际上是向远程主机提交一个新的文档 。 所以,一个查询string不(语义上)是有意义的。 这就是为什么你没有在应用程序代码中访问它们的原因。

POST稍微复杂一点(而且更灵活):

当接收到一个POST请求时,你应该总是期望一个“有效载荷”,或者,在HTTP方面:一个消息体 。 消息体本身是没用的,因为没有标准 (据我所知可能是application / octet-stream?)格式。 正文格式由Content-Type标题定义。 当使用method="POST"的HTML FORM元素时,通常是application/x-www-form-urlencoded 。 如果使用file upload,另一个非常常见的types是multipart / form-data 。 但可以是任何东西 ,从text/plainapplication/json甚至自定义application/octet-stream

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

大多数编程语言(和/或Web框架)提供了一种方法来将消息主体从/最常见的types(比如application/x-www-form-urlencodedmultipart/form-dataapplication/json ) 。 所以这很容易。 自定义types需要更多的工作。

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

  1. 阅读Content-Type字段
  2. 如果该值不是支持的媒体types之一,则返回带有415状态码的响应
  3. 否则,解码来自消息体的值。

再次,像PHP这样的语言,或者其他stream行语言的网页框架可能会为你处理。 这个例外是415错误。 没有框架可以预测你的应用程序select支持和/或不支持哪些内容types。 这取决于你。

PUT( 相关RFC部分 )

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

相比之下, PUT请求应该准确地该URI “存放”资源,并准确地存储该内容。 不多不less。 这个想法是客户负责在“推销”之前制作完整的资源。 服务器应该在给定的URL上按原样接受它。

因此, POST请求通常不用于replace现有资源。 PUT请求既可以创build也可以replace。

边注

还有一些“ path参数 ”可以用来向远程发送附加数据,但是它们是非常罕见的,我不会在这里详细讨论。 但是,作为参考,这里是从RFC的摘录:

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

您无法直接在浏览器url栏上input。

例如,您可以看到如何使用Live HTTP Headers在Internet上发送POST数据。 结果会是这样的

 http://127.0.0.1/pass.php POST /pass.php HTTP/1.1 Host: 127.0.0.1 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate DNT: 1 Referer: http://127.0.0.1/pass.php Cookie: passx=87e8af376bc9d9bfec2c7c0193e6af70; PHPSESSID=l9hk7mfh0ppqecg8gialak6gt5 Connection: keep-alive Content-Type: application/x-www-form-urlencoded Content-Length: 30 username=zurfyx&pass=password 

它在哪里说

 Content-Length: 30 username=zurfyx&pass=password 

将是岗位价值。

POST请求中的默认媒体types是application/x-www-form-urlencoded 。 这是编码键值对的格式。 密钥可以重复。 每个键值对都由一个&字符分隔,并且每个键与其值通过=字符分隔。

例如:

 Name: John Smith Grade: 19 

编码为:

 Name=John+Smith&Grade=19 

这被放置在HTTP标头之后的请求主体中。

HTTP POST中的表单值在请求正文中以与查询string相同的格式发送。

有关更多信息,请参阅规格 。

某些networking服务要求您分别放置请求数据元数据 。 例如,一个远程函数可能期望签名的元数据string被包含在一个URI中,而数据被发布在一个HTTP主体中。

POST请求在语义上可能如下所示:

 POST /?AuthId=YOURKEY&Action=WebServiceAction&Signature=rcLXfkPldrYm04 HTTP/1.1 Content-Type: text/tab-separated-values; charset=iso-8859-1 Content-Length: [] Host: webservices.domain.com Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding: identity User-Agent: Mozilla/3.0 (compatible; Indy Library) name id John G12N Sarah J87M Bob N33Y 

这种方法在逻辑上将QueryString和Body-Post结合起来,使用一个单一的Content-Type ,它是一个Web服务器的“parsing指令”。

请注意: HTTP / 1.1的左边是#32 (空格),右边是#10 (换行)。