四种常见的 POST 提交数据方式(application/x-www-form-urlencoded,multipart/form-data,application/json,text/xml)

转载:https://www.topjishu.com/6324.html

HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种。其中 POST 一般用来向服务端提交数据,本文主要讨论 POST 提交数据的几种方式。

我们知道,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为三个部分:状态行、请求头、消息主体。类似于下面这样:

<method> <request-URL> <version>
<headers>
<entity-body>

协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。

但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。下面就正式开始介绍它们。

application/x-www-form-urlencoded

这应该是最常见的 POST 提交数据的方式了。浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了):

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

首先,Content-Type 被指定为 application/x-www-form-urlencoded;其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持。例如 PHP 中,$_POST[‘title’] 可以获取到 title 的值,$_POST[‘sub’] 可以得到 sub 数组。

很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 和 QWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」。

multipart/form-data

这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 form 的 enctyped 等于这个值。直接来看一个请求示例:

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 mutipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 –boundary 开始,紧接着内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 –boundary– 标示结束。关于 mutipart/form-data 的详细定义,请前往 rfc1867 查看。

这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。

上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段原生 form 表单也只支持这两种方式。但是随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。

application/json

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。

Google 的 AngularJS 中的 Ajax 功能,默认就是提交 JSON 字符串。例如下面这段代码:

var data = {'title':'test''sub' : [1,2,3]};
$http.post(url, data).success(function(result) {
    ...
});

最终发送的请求是:

POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}

这种方案,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。各大抓包工具如 Chrome 自带的开发者工具、Firebug、Fiddler,都会以树形结构展示 JSON 数据,非常友好。但也有些服务端语言还没有支持这种方式,例如 php 就无法通过 $_POST 对象从上面的请求中获得内容。这时候,需要自己动手处理下:在请求头中 Content-Type 为 application/json 时,从 php://input 里获得原始输入流,再 json_decode 成对象。一些 php 框架已经开始这么做了。

当然 AngularJS 也可以配置为使用 x-www-form-urlencoded 方式提交数据。如有需要,可以参考这篇文章

text/xml

我的博客之前提到过 XML-RPC(XML Remote Procedure Call)。它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范。典型的 XML-RPC 请求是这样的:

POST http://www.example.com HTTP/1.1
Content-Type: text/xml
<?xml version="1.0"?>
<methodCall>
    <methodName>examples.getStateName</methodName>
    <params>
        <param>
            <value><i4>41</i4></value>
        </param>
    </params>
</methodCall>

XML-RPC 协议简单、功能够用,各种语言的实现都有。它的使用也很广泛,如 WordPress 的 XML-RPC Api,搜索引擎的 ping 服务等等。JavaScript 中,也有现成的库支持以这种方式进行数据交互,能很好的支持已有的 XML-RPC 服务。不过,我个人觉得 XML 结构还是过于臃肿,一般场景用 JSON 会更灵活方便。

四种常见的 POST 提交数据方式(application/x-www-form-urlencoded,multipart/form-data,application/json,text/xml)的更多相关文章

  1. (转)四种常见的 POST 提交数据方式

    四种常见的 POST 提交数据方式(转自:https://imququ.com/post/four-ways-to-post-data-in-http.html) HTTP/1.1 协议规定的 HTT ...

  2. application/json 四种常见的 POST 提交数据方式

    四种常见的 POST 提交数据方式   HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 ...

  3. 转:application/json 四种常见的 POST 提交数据方式

    四种常见的 POST 提交数据方式 HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 PO ...

  4. 【http】四种常见的 POST 提交数据方式

    来源:http://www.cnblogs.com/aaronjs/p/4165049.html HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT ...

  5. 四种常见的 POST 提交数据方式

    HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 POST 一般用来向服务端提交数据,本文 ...

  6. Web 四种常见的POST提交数据方式

    HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 POST 一般用来向服务端提交数据,本文 ...

  7. !!!四种常见的 POST 提交数据方式(含application/json)

    HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 POST 一般用来向服务端提交数据,本文 ...

  8. (转载)四种常见的 POST 提交数据方式

    (转载)http://www.imququ.com/post/four-ways-to-post-data-in-http.html HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS ...

  9. 【转】四种常见的POST提交数据方式

    HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 POST 一般用来向服务端提交数据,本文 ...

随机推荐

  1. WebLogic: 内存溢出

    每次部署完项目,重启Weblogic服务,总是遇到java.lang.OutOfMemoryError: PermGen space,其实物理内存也是够的,当时的解决方法就是多重启几次Weblogic ...

  2. 表格属性和BFC(block framing content)

    th和tr都是表示列但是 th有一个居中加粗的效果. 表单是由 : 1表单域:<form name=" " method="get/post"  acti ...

  3. Linux 下如何知道是否有人在使坏?

    在 Linux 下查看用户的行为,不仅仅是网管要做的事,也是开发人员所应该具备的基本技能之一.为什么呢?因为有时其他同事在做一些很消耗资源的事情,比如在编译大型程序,可能会导致服务器变得很慢,从而影响 ...

  4. 通过Oracle DUMP 文件获取表的创建语句

    1. 有了dump文件之后 想获取表的创建语句. 之前一直不知道 dump文件能够直接解析文件. 今天学习了下 需要的材料. dump文件, dump文件对应的schema和用户. 以及一个版本合适的 ...

  5. Linux 更改root与home分区大小的方法总结

    1. 安装了CentOS7.5的虚拟机 但是发现里面的操作系统 home 分区占到了400g 根分区只有50g 认为不太好,所以要改一下. 2.方法. 好像是xfs的文件格式, 没法使用resize2 ...

  6. Lodop设置打印维护返回打印语句代码

    打印设计关闭时,可以返回设计的打印代码,打印维护则返回成功打印的次数.不过打印维护也是返回打印程序代码的,方法就是加个语句,这个语句是: LODOP.SET_PRINT_MODE("PRIN ...

  7. Essential Phone PH1官方刷机方法

    Essential Phone官方有两种包 一种是ota包,即sideload线刷使用的包.但此刷机方法只能ota升级,不能降级. 另一种是Images包,即fastboot线刷使用的包.这种方法可以 ...

  8. Nginx ACCESS阶段 统一的用户权限验证系统

    L59 需要编译到Nginx --with-http_auth_request_module 功能介绍: 主要当收到用户请求的时候 通过反向代理方式生成子请求至上游服务器,如果上游服务器返回2xx 则 ...

  9. Linux 编译命令参数

    基本格式:gcc [options] file1 file2... //若不加入参数,则按默认参数依次执行编译.汇编和链接操作,生成的可执行文件名为 a.out 常用参数:-E //只执行预处理操作 ...

  10. Harmonic Number (II) LightOJ - 1245 (找规律?。。。)

    题意: 求前n项的n/i  的和 只取整数部分 暴力肯定超时...然后 ...现在的人真聪明...我真蠢 觉得还是别人的题意比较清晰 比如n=100的话,i=4时n/i等于25,i=5时n/i等于20 ...