在 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 一起发送。
价值观在哪里?在请求标头中?在请求正文中?它是什么样子的?
这些值以内容类型指定的格式在请求正文中发送。
通常内容类型是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-urlencoded
或的媒体类型发送multipart/form-data
。设计用于处理网络请求的编程语言或框架通常对此类请求执行“The Right Thing™”,并为您提供对易于解码的值的轻松访问(如PHP 中的 或 ,或$_REQUEST
Python中的 )。$_POST
cgi.FieldStorage()
flask.request.form
现在让我们离题一点,这可能有助于理解其中的区别;)
GET
和请求之间的区别POST
主要是语义上的。它们也以不同的方式“使用”,这解释了值传递方式的差异。
执行GET
请求时,您向服务器请求一个或一组实体。为了允许客户端过滤结果,它可以使用 URL 的所谓“查询字符串”。查询字符串是?
. 这是URI 语法的一部分。
因此,从您的应用程序代码(接收请求的部分)的角度来看,您将需要检查 URI 查询部分以访问这些值。
请注意,键和值是 URI 的一部分。浏览器可能会对 URI 长度施加限制。HTTP 标准声明没有限制。但在撰写本文时,大多数浏览器确实限制了 URI(我没有具体的值)。GET
请求永远不应该用于向服务器提交新信息。特别是不是更大的文件。那是你应该使用POST
or的地方PUT
。
执行POST
请求时,客户端实际上是在向远程主机提交一个新文档。因此,查询字符串(在语义上)没有意义。这就是为什么您无法在应用程序代码中访问它们的原因。
POST
有点复杂(而且更灵活):
接收 POST 请求时,您应该始终期待“有效负载”,或者用 HTTP 术语来说:消息正文。消息体本身没什么用,因为没有标准(据我所知。也许是应用程序/八位字节流?)格式。正文格式由Content-Type
标头定义。当使用带有 的 HTMLFORM
元素时method="POST"
,通常是application/x-www-form-urlencoded
. 如果您使用文件上传,另一种非常常见的类型是multipart/form-data 。但它可以是任何东西,范围从text/plain
、超过application/json
甚至是一种习惯application/octet-stream
。
在任何情况下,如果使用应用程序无法处理的POST
请求,它应该返回一个status-code。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 上,并准确地包含该内容。不多也不少。这个想法是客户负责在“PUT”之前制作完整的资源。服务器应该在给定的 URL 上按原样接受它。
因此,POST
通常不使用请求来替换现有资源。一个PUT
请求既可以创建也可以替换。
还有一些“路径参数”可以用来向远程发送额外的数据,但是它们太少见了,这里我就不多说了。但是,作为参考,这里是 RFC 的摘录:
除了层次路径中的点段之外,路径段被通用语法认为是不透明的。生成 URI 的应用程序通常使用段中允许的保留字符来分隔特定于方案或特定于解引用处理程序的子组件。例如,分号 (";") 和等号 ("=") 保留字符通常用于分隔适用于该段的参数和参数值。逗号 (",") 保留字符通常用于类似目的。例如,一个 URI 生产者可能使用诸如“name;v=1.1”之类的段来指示对“name”的 1.1 版本的引用,而另一个 URI 生产者可能使用诸如“name,1.1”之类的段来指示相同。参数类型可以由特定于方案的语义定义,
您不能直接在浏览器 URL 栏上键入它。
例如,您可以看到 POST 数据如何通过Live HTTP Headers在 Internet 上发送。结果将是这样的
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 请求中的默认媒体类型是application/x-www-form-urlencoded
. 这是一种编码键值对的格式。密钥可以重复。每个键值对由一个&
字符分隔,每个键与其值由一个=
字符分隔。
例如:
Name: John Smith
Grade: 19
被编码为:
Name=John+Smith&Grade=19
这放置在 HTTP 标头之后的请求正文中。
HTTP POST 中的表单值在请求正文中发送,格式与查询字符串相同。
有关详细信息,请参阅规范。
某些 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
(换行符)。
首先,让我们区分GET
和POST
Get:它是向服务器发出的默认HTTP
请求,用于从服务器检索数据,?
a 后面的查询字符串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 的 header 中,并且没有重要数据直接附加到 URL。
您可以使用 Google Developer Tools 的网络部分来查看有关如何向服务器发出请求的基本信息。
而且你总是可以在你Request Headers
喜欢Cache-Control
的 , Origin
,中添加更多的值Accept
。
post参数有多种方式/格式
它们由表示为 mime 类型的 Header 中的内容类型控制。