如何在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-urlencoded
或multipart/form-data
。 编程语言或框架已被devise为处理networking请求通常做“正确的事情™”与这样的要求,并为您提供轻松获取解码值(如$_REQUEST
或$_POST
在PHP中,或cgi.FieldStorage()
,Python中的flask.request.form
)。
现在让我们稍微离题,这可能有助于理解差异;)
GET
和POST
请求之间的区别在很大程度上是语义上的。 它们也被“使用”了,这就解释了值如何传递的不同。
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/plain
, application/json
甚至自定义application/octet-stream
。
在任何情况下,如果POST
请求是由应用程序无法处理的Content-Type
的,则应该返回一个415
状态码 。
大多数编程语言(和/或Web框架)提供了一种方法来将消息主体从/最常见的types(比如application/x-www-form-urlencoded
, multipart/form-data
或application/json
) 。 所以这很容易。 自定义types需要更多的工作。
以标准HTML表单编码文档为例,应用程序应执行以下步骤:
- 阅读
Content-Type
字段 - 如果该值不是支持的媒体types之一,则返回带有
415
状态码的响应 - 否则,解码来自消息体的值。
再次,像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
(换行)。