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

How are parameters sent in an HTTP POST request?

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

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

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

价值观在哪里?在请求头中?在请求主体中?它是什么样子的?


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

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

1
parameter=value&also=another

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


内容放在HTTP头之后。HTTP POST的格式是让HTTP头后跟一个空白行,再跟请求主体。post变量在主体中存储为键值对。

您可以在http文章的原始内容中看到这一点,如下所示:

1
2
3
4
5
6
7
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请求中,值在请求的"正文"中发送。对于web表单,它们最有可能使用application/x-www-form-urlencodedmultipart/form-data的媒体类型发送。为处理Web请求而设计的编程语言或框架通常做"正确的事情"?有了这些请求,您就可以方便地访问容易解码的值(如php中的$_REQUEST$_POST,或者python中的cgi.FieldStorage()flask.request.form)。好的。

现在让我们离题一点,这可能有助于理解区别;)好的。

GETPOST请求之间的差异很大程度上是语义上的。它们的"使用"也不同,这就解释了如何传递值的不同。好的。GET(相关RFC部分)

当执行GET请求时,您向服务器请求一个或一组实体。为了允许客户机过滤结果,它可以使用URL的所谓"查询字符串"。查询字符串是?后面的部分。这是URI语法的一部分。好的。

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

请注意,键和值是URI的一部分。浏览器可能会对URI长度施加限制。HTTP标准规定没有限制。但在撰写本文时,大多数浏览器确实限制了URI(我没有特定的值)。不应使用GET请求向服务器提交新信息。尤其是大文件。这就是你应该使用POSTPUT的地方。好的。岗位(相关RFC部分)

当执行POST请求时,客户机实际上正在向远程主机提交一个新的文档。因此,查询字符串(语义上)没有意义。这就是为什么在应用程序代码中您不能访问它们。好的。

POST有点复杂(而且更灵活):好的。

当接收到一个POST请求时,您应该总是期望一个"有效负载",或者用HTTP术语来说:一个消息体。消息体本身是非常无用的,因为没有标准(据我所知)。可能是应用程序/八位字节流?)格式。正文格式由Content-Type头定义。当将html FORM元素与method="POST"一起使用时,通常是application/x-www-form-urlencoded。另一种非常常见的类型是多部分/表单数据(如果使用文件上载)。但是它可以是任何东西,从text/plain,到application/json,甚至是自定义的application/octet-stream。好的。

在任何情况下,如果使用应用程序无法处理的Content-Type请求POST请求,则应返回415状态代码。好的。

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

以标准HTML表单编码文档为例,应用程序应执行以下步骤:好的。

  • 读取Content-Type字段
  • 如果该值不是支持的媒体类型之一,则返回带有415状态代码的响应
  • 否则,对消息体中的值进行解码。
  • 同样,像PHP或其他流行语言的Web框架之类的语言可能会为您处理这些问题。例外情况是415错误。没有框架能够预测应用程序选择支持和/或不支持哪些内容类型。这由你决定。好的。Put(相关RFC部分)

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

    相比之下,PUT请求应该在该URI上"存储"一个资源,并使用该内容。不多不少。其理念是,客户负责在"投入"资源之前创造出完整的资源。服务器应该接受给定URL上的内容。好的。

    因此,POST请求通常不用于替换现有资源。PUT请求既可以创建也可以替换。好的。边注

    还有一些"路径参数"可以用来向远程服务器发送额外的数据,但它们非常罕见,我在这里不会详细介绍。但是,作为参考,这里有一个来自RFC的摘录:好的。

    Aside from dot-segments in hierarchical paths, a path segment is considered
    opaque by the generic syntax. URI producing applications often use the
    reserved characters allowed in a segment to delimit scheme-specific or
    dereference-handler-specific subcomponents. For example, the semicolon (";")
    and equals ("=") reserved characters are often used to delimit parameters and
    parameter values applicable to that segment. The comma (",") reserved
    character is often used for similar purposes. For example, one URI producer
    might use a segment such as"name;v=1.1" to indicate a reference to version
    1.1 of"name", whereas another might use a segment such as"name,1.1" to
    indicate the same. Parameter types may be defined by scheme-specific
    semantics, but in most cases the syntax of a parameter is specific to the
    implementation of the URIs dereferencing algorithm.

    Ok.

    好啊。


    不能直接在浏览器的URL栏上键入。

    例如,您可以看到如何通过实时HTTP头在Internet上发送日志数据。结果会是这样的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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

    在哪里说

    1
    2
    Content-Length: 30
        username=zurfyx&pass=password

    将是post值。


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

    例如:

    1
    2
    Name: John Smith
    Grade: 19

    编码为:

    1
    Name=John+Smith&Grade=19

    这将放在HTTP头后面的请求主体中。


    一些Web服务要求您分别放置请求数据和元数据。例如,远程函数可能期望签名的元数据字符串包含在URI中,而数据发布在HTTP主体中。

    POST请求在语义上可能如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    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

    这种方法使用单个Content-Type,逻辑上结合了querystring和body post,后者是Web服务器的"解析指令"。

    请注意:http/1.1的包装左侧为EDOCX1(空格),右侧为EDOCX1(换行)。


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

    有关详细信息,请参见规范。


    首先,我们来区分GETPOST

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

    这是格式

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

    这里,data=value是传递的查询字符串值。

    post:它用于将数据安全地发送到服务器,以便在需要时使用,这是POST请求的格式。

    1
    2
    3
    4
    5
    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中,发送到服务器的值通常附加到查询字符串中的基URL,这使您的数据能够被黑客攻击(在Facebook中,这在几天内是一个问题,在Facebook中,您的凭据被公开),这就是为什么POST被用于向使用Request Body将数据发送到服务器的原因。ER更安全,因为它隐藏了您的数据,加上它从字段中获取您的数据,计算它们的长度,并将它们添加到header中,用于content-length,并且没有重要数据直接附加到URL

    既然您的请求是安全的,那么任何发送到服务器的值都可以在Request Body中发送,因为名称意味着它将包含用户想要发送的数据(并且以URL Encoded格式发送),并且Request Headers将通过比较Request BodyRequest Headers中的值来保持请求的安全性。

    您可以使用Google开发人员工具的网络部分查看有关如何向服务器发出请求的基本信息。

    你可以在你的Request Headers中添加更多的值,比如Cache-ControlOriginAccept