在 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: [email protected]
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
。设计用于处理 Web 请求的编程语言或框架通常使用此类请求执行 “正确的 Thing™”,并为您提供对易于解码的值的轻松访问(例如 PHP 中的$_REQUEST
或$_POST
,或cgi.FieldStorage()
,在 Python 中使用flask.request.form
)。
现在让我们稍微离题,这可能有助于理解差异;)
GET
和POST
请求之间的区别主要是语义上的。它们也被 “使用” 不同,这解释了值的传递方式的差异。
执行GET
请求时,您向服务器询问一个或一组实体。要允许客户端过滤结果,它可以使用 URL 的所谓 “查询字符串”。查询字符串是后面的部分?
。这是URI 语法的一部分。
因此,从应用程序代码( 接收请求的部分)的角度来看,您需要检查 URI 查询部分以获取对这些值的访问权限。
请注意,键和值是 URI 的一部分。浏览器可能会对 URI 长度施加限制。 HTTP 标准规定没有限制。但在撰写本文时,大多数浏览器确实限制了 URI(我没有特定的值)。 绝不应使用GET
请求向服务器提交新信息。特别是不大的文件。这就是你应该使用POST
或PUT
。
执行POST
请求时,客户端实际上是在向远程主机提交新文档 。因此, 查询字符串(语义上)没有意义。这就是您无法在应用程序代码中访问它们的原因。
POST
是更复杂的(和方式更灵活)一点点:
收到 POST 请求时,您应该总是期望 “有效负载”,或者在 HTTP 术语中: 消息体 。消息体本身是没用的,因为没有标准 (据我所知。也许是 application / octet-stream?)格式。正文格式由Content-Type
标头定义。使用带有method="POST"
的 HTML FORM
元素时,通常是application/x-www-form-urlencoded
。如果您使用文件上传,另一种非常常见的类型是multipart / form-data 。但是可能是任何东西 ,从text/plain
, application/json
甚至是自定义application/octet-stream
。
在任何情况下,如果POST
请求是使用应用程序无法处理的Content-Type
,则应返回415
状态代码 。
大多数编程语言(和 / 或 Web 框架)提供了一种从最常见的类型(对于application/x-www-form-urlencoded
, multipart/form-data
或application/json
)对消息体进行解码 / 编码的方法。 。这很容易。自定义类型可能需要更多工作。
使用标准 HTML 表单编码文档作为示例,应用程序应执行以下步骤:
Content-Type
字段415
状态代码的响应同样,PHP 等语言或其他流行语言的 Web 框架可能会为您处理此问题。例外是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” 之类的段来表示相同。参数类型可以由特定于方案的语义定义,但是在大多数情况下,参数的语法特定于 URI 解除引用算法的实现。