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

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

文章目录

  • application/x-www-form-urlencoded
  • multipart/form-data
  • application/json
  • text/xml

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

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

BASH<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 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了):

BASHPOST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8title=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> 表单的 enctype 等于 multipart/form-data。直接来看一个请求示例:

BASHPOST 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/pngPNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

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

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

上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 <form> 表单也只支持这两种方式(通过 <form> 元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded。其实 enctype 还支持 text/plain,不过用得非常少)。

随着越来越多的 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 字符串。例如下面这段代码:

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

最终发送的请求是:

BASHPOST 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 请求是这样的:

HTMLPOST 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 会更灵活方便。

转载于:https://www.cnblogs.com/aishangliming/p/6086935.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469902.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

成功驱动5150用HT68F30

用了自己写的起动总线和停止总线&#xff0c;终于可以成功 // PROGRAM : 4-17.c 2011.0521 // FUNCTION : I2C Master/Slave Mode Demo Program By Steven // Note : Configuration Option Setting-- // SIM Function Enable //void I2C_START(void); /…

VMware 虚拟机 Ubuntu 系统执行 ifconfig 命令 eth0没有IP地址(intet addr、Bcast、Mask)

可能的原因是&#xff0c;你安装了也安装了其他的虚拟机软件&#xff0c;比如&#xff1a;VirtualBox。我们打开 控制面板 > 网络和共享中心 > 更改适配器设置 &#xff0c; 你就可以打开控制面板/网络和Internet/网络连接界面&#xff1a; 直接禁用相应的网络即可&#…

sublime text3c语言编译运行,c – Sublime text 3 – 编译程序并在终端中运行

我正在使用Ubuntu 12.04,我想知道,是否有可能从终端自动运行c程序&#xff1f;当你不得不在构建控制台中使用它时,它真的很糟糕,因为有时候我会意外地创建无限循环,并且必须重新启动sublime文本再次工作.我正在使用Sublime文本3.解决方法:Sublime Text 3包含两个您可能感兴趣的…

5150晶振不起振

1、这是一个比较让我费解的问题、今天从相机输入了PAL信号、发现根本没有解码出来&#xff0c;然后检查检查&#xff0c;发现晶振不起振 解决中。。。 1、换一个板子&#xff0c;看是不是这个板子出了问题、 2、换一个起振电容 问题解决了、原因是TVP5150的PDN脚应该输入高电…

c语言us16 t,使用C ++将越南语字符编码为USASCII,ISO88591,UTF8,UTF16BE,UTF16LE,UTF16(示例代码)...

我已经编辑了我的帖子。当前&#xff0c;我正在尝试对用户的输入字符串进行编码&#xff0c;然后将其转换为每种编码格式。我可以使用Unicode完美地做到这一点&#xff0c;而且我认为输入String的格式为UTF-8。如果我的inputString是“ Hello”。但是&#xff0c;当我尝试输入“…

linux一些基础知识

linux面试题及答案 一&#xff0e;填空题&#xff1a; 1. 在Linux系统中&#xff0c;以 文件 方式访问设备 。 2. Linux内核引导时&#xff0c;从文件 /etc/fstab 中读取要加载的文件系统。 3. Linux文件系统中每个文件用 i节点来标识。 4. 全部磁盘块由四个部分组成&#xff…

这本轻小说真厉害 2016

傲娇御坂美琴成轻小说女王一姐 轻小说排名公布 到了年底,作为轻小说的粉丝就没有理由不关注“这本轻小说真厉害!”的相关评选吧?腾讯动漫此前曾经报道过《OVERLORD》以及《龙王的工作》获得榜首殊荣的消息。而近日,年度的最佳作品、最佳角色以及最佳插画师等奖项也已经公布,快…

IDEA初次使用Tomcat运行项目(如何添加加载项目到Tomcat)

IDEA中Tomcat设置说明 Tomcat最好使用干净的版本 不同的版本适配不同的JDK 设置Tomcat基本信息 加载项目&#xff08;war和war exploed模式简单说明&#xff09; 配置完项目后警告消失 应用后启动 选择相应的模式即可

回溯算法背包问题迭代c语言,回溯法解决0_1背包问题(迭代和递归)

问题&#xff1a;0/1背包问题例子:weight数组代表物品重量&#xff0c;value数组代表物品价值&#xff0c;M代表背包容量。背包是按单位价值递减的顺序排列的&#xff0c;即value[i]/weight[i]>value[i-1]/weight[i-1].const int weight[Max]{1,11,21,23,33,43,45,55};const…

ISE应用入门的一些问题

1、怎样添加IP 2、怎样用modelsim调用IP生成的仿真文件。 今天用modelsim仿真ISE生成的DDR IP IP核的地址&#xff1a;E:\FPGA\MIS607\Mis607B\update\CH09_DDR_TEST\MiS607B_DDR3_Test\DDR3_Test\ipcore_dir\mig_ddr3_control\example_design\sim\functional 所以要把modelsim…

linux模块加载和模块卸载时出现的问题

在编写驱动程序的时候有时候会出现这种情况&#xff0c;模块加载之后不能卸载或卸载之后不能在加载&#xff0c;cat /proc/devices 后发现设备还占用着设备号&#xff0c;这种情况下&#xff0c;再次加载驱动模块肯定不会成功&#xff0c;必须重新启动才可以解决。最近仔细看书…

IDEA中中文乱码问题解决方案

1.修改idea安装目录下的两个文件 C:\Program Files\JetBrains\IntelliJ IDEA 2017.1.4\bin\idea.exe.vmoptions C:\Program Files\JetBrains\IntelliJ IDEA 2017.1.4\bin\idea64.exe.vmoptions 在这两个文件下增加一行: -Dfile.encodingUTF-8 2.做此修改后,tomcat运行日志会…

linux 6.2 期末考试题,redhat6.2-linux考试试卷(带部分答案)

这个是初学redhat6.2的考试内容,带答案(实做的,水平有限,不完整答案)--------------------------------------------------------------------------------------------装 订 线-----------------------------------------------------------------------------------------广东…

ios几个重要方法

加载类到内存&#xff0c;程序刚启动的时候调用&#xff0c;调用在main函数之前 1.(void)load{} 初始化类&#xff0c;类第一次使用的时候调用一次 2.(void)initialize{ } 控制器的视图架构&#xff0c;设置控制器的根view&#xff0c;重写该方法后&#xff0c;以该方法为主&am…

C++中extern “C”含义深层探索

1.引言 C语言的创建初衷是“a better C”&#xff0c;但是这并不意味着C中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同。作为一种欲与C兼容的语言&#xff0c;C保留了一部分过程式语言的特点&#xff08;被世人称为“不彻底地面向对象”&#xff09;&…

video4linux 安装,【精品博文】Video4linux 下视频编程的流程

最近一直在忙基金申报&#xff0c;今天终于顺利提交了&#xff0c;剩下的就看缘分啦。今天有时间写写Video4linux 下视频编程的流程。Video4linux(简称 V4L),是linux 中关于视频设备的内核驱动。现在已有Video4linux2&#xff0c;还未加入linux 内核&#xff0c;使用的时候要自…

TVP5150真正的驱动起来了

几个注意的地方&#xff1a; 1、驱动TVP5150所需要的是IIC来驱动、IIC的时序一定要搞清楚、还有IIC的读写时序、 刚开始的时候并尝试从里面读寄存器、没有成功、可能有些寄存器不能读、2、硬件一定要检查清楚&#xff0c;TVP5150用到的电源有3.3V 1.8V、用电压表测量好、3、检查…

intellij IDEA--- 报inspects a maven model for resolution problems

解决方法是&#xff1a; 第一种&#xff1a; 找到pom.xml 右击 --> Maven --> reImport 第二种方法&#xff1a; 第三种 <properties><junit.version>4.11</junit.version><spring.version>4.3.14.RELEASE</spring.version></prop…