在HTTP GET请求中,参数作为查询字符串发送:
http://example.com/page?parameter = value&also = another
在HTTP POST请求中,参数不会与URI一起发送。
价值在哪里?在请求标头中?在请求正文中?它是什么样子的?
在HTTP GET请求中,参数作为查询字符串发送:
http://example.com/page?parameter = value&also = another
在HTTP POST请求中,参数不会与URI一起发送。
价值在哪里?在请求标头中?在请求正文中?它是什么样子的?
Answers:
值以内容类型指定的格式在请求正文中发送。
通常,内容类型为application/x-www-form-urlencoded
,因此请求正文使用与查询字符串相同的格式:
parameter=value&also=another
当您使用表单中的文件上传功能时,将使用multipart/form-data
编码格式,而编码格式则不同。它比较复杂,但是您通常不需要关心它的外观,因此我不会显示示例,但是知道它的存在可能会很好。
multipart/form-data
,或者如果你在充电要求建设,改变内容类型的很对application/json
,并在HTTP主体直接粘贴JSON文本
内容放在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请求和响应有效负载。
application/x-www-form-urlencoded
为时,情况并非总是如此。
From
那里有标题?
From
标题的随机包含。IMO,它带有418 HTTP状态代码。
简短的答案:在POST请求中,值在请求的“正文”中发送。对于网络表单,最有可能以application/x-www-form-urlencoded
或的媒体类型发送它们multipart/form-data
。编程语言或已被设计用于处理网络请求通常做“正确的事情™”这样的请求,并为您提供轻松前往容易解码值(如框架$_REQUEST
或$_POST
PHP中,或者cgi.FieldStorage()
,flask.request.form
在Python)。
现在让我们讨论一下,这可能有助于理解差异;)
GET
和POST
请求之间的区别主要是语义上的。它们也以不同的方式“使用”,这解释了如何传递值。
执行GET
请求时,您向服务器询问一个或一组实体。为了允许客户端过滤结果,它可以使用URL的所谓“查询字符串”。查询字符串是后面的部分?
。这是URI语法的一部分。
因此,从您的应用程序代码(接收请求的部分)的角度来看,您将需要检查URI查询部分以访问这些值。
请注意,键和值是URI的一部分。浏览器可能会对URI长度施加限制。HTTP标准规定没有限制。但是在撰写本文时,大多数浏览器的确会限制URI(我没有具体值)。GET
请求绝不能用于向服务器提交新信息。特别是没有较大的文档。那是您应该使用POST
或的地方PUT
。
执行POST
请求时,客户端实际上是在向远程主机提交新文档。因此,查询字符串(在语义上)没有意义。这就是为什么您无法在应用程序代码中访问它们的原因。
POST
有点复杂(方式也更灵活):
收到POST请求时,您应该始终期望“有效载荷”,或者用HTTP术语表示:消息正文。消息主体本身是没有用的,因为没有标准的格式(据我所知。也许是application / octet-stream?)。正文格式由Content-Type
标题定义。当与HTML FORM
元素一起使用时method="POST"
,通常为application/x-www-form-urlencoded
。如果使用文件上传,则另一种非常常见的类型是multipart / form-data。但这可能是任何东西,范围从text/plain
,结束application/json
甚至是习俗application/octet-stream
。
无论如何,如果使用POST
发出的请求Content-Type
都无法由应用程序处理,则它应返回415
状态码。
大多数编程语言(和/或网络框架)提供了一种方法来解/编码的邮件正文从/最常见的类型(如application/x-www-form-urlencoded
,multipart/form-data
或application/json
)。这很容易。自定义类型可能需要更多的工作。
以标准HTML表单编码的文档为例,应用程序应执行以下步骤:
Content-Type
领域415
状态码的响应同样,PHP之类的语言或其他流行语言的网络框架可能会为您解决这个问题。例外是415
错误。没有框架可以预测您的应用选择支持和/或不支持的内容类型。这取决于你。
一个PUT
请求几乎以与POST
请求完全相同的方式处理。最大的区别是POST
请求应该让服务器决定如何(如果有的话)创建新资源。从历史上看(从现在已过时的RFC2616开始,它是将新资源创建为发送请求的URI的“下级”(子级))。
甲PUT
相反请求应该恰好“存款”的资源在该URI,并用确切该内容。不多不少。这个想法是,客户有责任在“放入”之前制作完整的资源。服务器应在给定URL上原样接受它。
结果,POST
通常不使用请求来替换现有资源。一个PUT
请求可以创建和替换。
还有一些“ 路径参数 ”可用于将其他数据发送到远程,但是它们很少见,因此在此不再赘述。但是,作为参考,以下是RFC的摘录:
除了分层路径中的点段外,通用语法还认为路径段是不透明的。产生URI的应用程序通常使用段中允许的保留字符来分隔特定于方案或特定于解除引用处理程序的子组件。例如,分号(“;”)和等号(“ =”)保留字符通常用于定界适用于该段的参数和参数值。逗号(“,”)保留字符通常用于类似目的。例如,一个URI生产者可能使用诸如“ name; v = 1.1”之类的段来表示对“ name”的1.1版的引用,而另一家URI生产者可能使用诸如“ name,1.1”之类的段来表示相同。参数类型可以通过特定于方案的语义来定义,
PUT
节的第二段,您将看到它是幂等的。POST
相反,按照定义,可以不是。POST
将始终创建新资源。PUT
如果存在相同的资源,则将其替换。因此,如果调用POST
10次,则将创建10个资源。如果您拨打PUT
10次,它将(可能)仅创建一次。这是否回答你的问题?
您不能直接在浏览器URL栏上键入它。
例如,您可以查看如何使用实时HTTP标头在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
将是职位价值。
Content-Length
应该在29
这里吗?那是字符串的实际长度username=zurfyx&pass=password
。
POST请求中的默认媒体类型为application/x-www-form-urlencoded
。这是用于编码键值对的格式。密钥可以重复。每个键值对都由一个&
字符分隔,每个键与其值之间由一个=
字符分隔。
例如:
Name: John Smith
Grade: 19
编码为:
Name=John+Smith&Grade=19
它放在HTTP标头之后的请求正文中。
HTTP POST中的表单值以与查询字符串相同的格式在请求正文中发送。
有关更多信息,请参见规范。
?
以例如开头吗?
application/x-www-form-urlencoded
为时,情况并非总是如此。
某些Web服务要求您分别放置请求数据和元数据。例如,远程功能可能希望将签名的元数据字符串包含在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服务器的“解析指令”。
请注意: HTTP / 1.1 包裹与#32
左边,并用(空间)#10
右侧(行)。
/user/john
和之间的区别/?user=john
只是语义上的区别(HTTP并没有对查询字符串进行特殊处理),因此我认为这是合理的。但是,“用左边的空间包裹”是什么意思?HTTP方法前没有空格。您是说帖子正文的空白行吗?
...Ym04
和之间有一个空格(ASCII#32)HTTP/1.1
。因此,QueryString仅位于动词和协议版本之间。
?
就像处理GET
请求一样。
首先,让我们区分GET
和POST
获取:这是默认的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上,现在有2种结果
GET
请求与参数保存在浏览器历史记录。因此,您的密码在浏览器历史记录中保持未加密状态。过去,这对于Facebook来说是一个真正的问题。URI
。如果发送的参数太多,您可能会收到414 Error - URI too long
如果发布请求,则将字段中的数据添加到正文中。计算请求参数的长度,并将其添加到content-length的标头中,并且没有重要数据直接附加到URL。
您可以使用Google Developer Tools的网络部分来查看有关如何向服务器发出请求的基本信息。
你可以随时在你添加更多的价值Request Headers
一样Cache-Control
,Origin
,Accept
。
HTTPS
连接的情况下才成立,而在的情况下才成立HTTP
。HTTPS
加密两者URL
(包括查询参数)和Request Body
,当HTTP
加密/既不保护。所描述的问题来自许多浏览器将URIs
(包括URLs
)存储在其历史数据库中(通常未加密)的事实。因此,仅对敏感内容使用Request Body
+ HTTPS
。
multipart/form-data
。对于那些感兴趣的人,这是一个问题。