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

时间:2013-01-27 19:19:08

标签: http post parameters request uri

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

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

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

值在哪里? 在请求标头中?在请求机构?它看起来像什么?

8 个答案:

答案 0 :(得分:1119)

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

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

parameter=value&also=another

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

答案 1 :(得分:397)

内容放在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请求和响应有效负载。

答案 2 :(得分:330)

简短回答:在POST请求中,值会在" body"中发送。请求。对于网络表单,他们最有可能使用application/x-www-form-urlencodedmultipart/form-data的媒体类型发送。设计用于处理Web请求的编程语言或框架通常会执行“正确的事情”和#34;通过这些请求,您可以轻松访问易于解码的值(例如PHP中的$_REQUEST$_POST,或Python中的cgi.FieldStorage()flask.request.form


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

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

获取(relevant RFC section

执行GET请求时,您要求服务器提供一个或一组实体。为了允许客户端过滤结果,它可以使用所谓的"查询字符串"的URL。查询字符串是?之后的部分。这是URI syntax

的一部分

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

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

POST(relevant RFC section

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

POST稍微复杂一些(方式更灵活):

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

在任何情况下,如果POST请求的Content-Type请求无法由应用程序处理,则应返回415 status-code

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

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

  1. 阅读Content-Type字段
  2. 如果该值不是受支持的媒体类型之一,则返回带有415状态代码的响应
  3. 否则,解码邮件正文中的值。
  4. 同样,PHP等语言或其他流行语言的Web框架可能会为您处理此问题。例外是415错误。没有框架可以预测应用程序选择支持和/或不支持的内容类型。这取决于你。

    PUT(relevant RFC section

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

    相反,PUT请求应该是"存放"一个资源 at 该URI,正好该内容。不多也不少。我们的想法是客户端负责在" PUTting"之前制作完整的资源。它。服务器应该在给定的URL上接受 as-is

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

    边注

    还有" path parameters"可用于向遥控器发送附加数据,但它们非常罕见,我在这里不会详细说明。但是,作为参考,这里是RFC的摘录:

      

    除了分层路径中的点段之外,还考虑路径段   通用语法不透明。 URI生成应用程序经常使用   段中允许的保留字符用于分隔特定于方案或   dereference-handler特定的子组件。例如,分号(&#34 ;;")   和equals(" =")保留字符通常用于分隔参数和   适用于该细分的参数值。逗号(",")保留   字符通常用于类似目的。例如,一个URI生成器   可能会使用" name; v = 1.1"表示对版本的引用   名称"的1.1,而另一个可能使用" name,1.1"至   表示相同。参数类型可以由特定于方案定义   语义,但在大多数情况下,参数的语法特定于   URI解除引用算法的实现。

答案 3 :(得分:54)

您无法直接在浏览器网址栏中输入。

您可以看到如何使用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

将是帖子值。

答案 4 :(得分:20)

POST请求中的默认媒体类型是application/x-www-form-urlencoded。这是一种用于编码键值对的格式。密钥可以是重复的。每个键值对由&个字符分隔,每个键与=个字符的值分开。

例如:

Name: John Smith
Grade: 19

编码为:

Name=John+Smith&Grade=19

这是在HTTP标题之后放在请求正文中。

答案 5 :(得分:17)

某些网络服务要求您分别发出请求数据元数据。例如,远程函数可能期望签名的元数据字符串包含在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,这是一个"解析指令"对于网络服务器。

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

答案 6 :(得分:13)

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

有关详细信息,请参阅spec

答案 7 :(得分:3)

首先,让我们区分GETPOST

获取:这是对服务器的默认HTTP请求,用于从服务器中检索数据以及查询位于?之后的字符串URI用于检索唯一资源。

这是格式

GET /someweb.asp?data=value HTTP/1.0

此处data=value是传递的查询字符串值。

POST :它用于安全地将数据发送到服务器,因此需要任何内容​​,这是POST请求的格式

POST /somweb.aspHTTP/1.0
Host: localhost
Content-Type: application/x-www-form-urlencoded //you can put any format here
Content-Length: 11 //it depends
Name= somename

为什么要通过GET进行发布?

GET中,发送到服务器的值通常附加在查询字符串中的基本URL后面,这使您的数据能够被黑客入侵(这在几天前的Facebook上是一个问题,因为您的凭据在公开),这就是为什么使用POST将数据发送到服务器,而使用Request Body将数据发送到服务器的原因,这是更安全的,因为它隐藏了您的数据,而且还从字段计算中获取了数据它们的长度并将它们添加到header的{​​{1}}中,并且没有重要数据直接附加到content-length

现在,确保您的请求是安全的,可以将发送到服务器的任何值发送到URL中,顾名思义,它将包含用户想要发送的数据(并且发送到{{1 }}格式)和Request BodyURL EncodedRequest Headers

中的值进行比较,从而确保请求的安全性

您可以使用Google Developer Tools的网络部分来查看有关如何向服务器发出请求的基本信息。

,您随时可以在Request Body中添加更多值,例如Request HeadersRequest HeadersCache-Control