您的位置:首页 > 其它

Ajax方式提交表单的常见编码类型总结

2017-12-27 10:08 260 查看
用Ajax方式提交表单,决定编码类型的是请求头中
Content-Type
,不同的值对应不同的提交和回调处理方式。而且,在项目中我们会用到前端的库或者框架,他们对于不同的
Content-Type
也有不同的参数写法,本文将以jQuery和AngularJS,加上XMLHttpRequest共三种方式为例,详细介绍不同
Content-Type
的发送请求的方式。本文考虑的
Content-Type
类型,共有如下几种:

application/x-www-form-urlencoded

multipart/form-data

text/plain

application/json

text/xml

下面将介绍XMLHttpRequest、jQuery和AngularJS三种异步提交方式,及对应的每一种Conten-Type类型。


XMLHttpRequest 方式

XMLHttpRequest对象用于向后端收发数据请求,现代浏览器都支持(IE要用ActiveXObject实现相同功能,本文就不讨论了)。

后续代码将假设已经获得了XMLHttpRequest对象,其名为
req
。下面将介绍XMLHttpRequest对象用常见的五种
Content-Type
发送数据的方式。


application/x-www-form-urlencoded

这种
Content-Type
要求数据按照
key1=value1&key2=value2
的格式发送给后端,且其中的特殊字符需要转义成
%HH
的形式。

首先,需要用
encodeURIComponent()
函数编码表单数据,代码如下。
/* data参数为表单数据组成的对象,dataToSend为待发送给后端的数据 */

var tempArr = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
tempArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
}

var dataToSend = tempArr.join('&');


接着,设置请求头部的
Content-Type
,发送数据,代码如下。
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send(dataTosend);


multipart/form-data

这种
Content-Type
类型多用来提交文件,我们采用HTML5的FormData对象来构建提交的数据。FormData对象的浏览器支持情况见:FormData对象的浏览器支持情况。基本上现代浏览器都支持,IE11以下不支持,不支持的建议用ajaxForm之类的jquery的文件提交插件吧。

首先,用FormData对象构建欲提交的数据,代码如下。
/* data参数为表单数据组成的对象,dataToSend为待发送给后端的数据 */

var dataToSend = new FormData();      // HTML5对象, IE11以下不支持
for (var key in data) {
if (data.hasOwnProperty(key)) {
dataToSend.append(key, data[key]);
}
}

// dataToSend就是FormData对象,可直接传给后端
dataToSend


接着,直接发送给后端,注意这种类型的发送方式,不能设置请求头部的
Content-Type
,应交给浏览器来处理(设定Boundary等工作)。
req.send(dataToSend);


text/plain

如果请求头部没有设定
Content-Type
,且数据既不是
FormData
也不是
XML
Document
(将在xml小节中介绍),则
Content-Type
默认为
text/plain


这种方式的代码很简单,直接发送字符串即可,代码如下。
req.send('...(此处是字符串格式的数据)');


application/json

JSON格式的数据,后端和各种移动端都很方便处理,用这种MIME类型时,需要将数据对象转换成JSON串。

首先,转换数据成JSON串;然后,设定请求头部的
Content-Type
,就可以发数据了。代码如下。
/* data参数为表单数据组成的对象 */

req.send( JSON.stringify(data) );


text/xml

目前没有遇到过要用XML的情况,大部分都可用JSON代替,为了完整起见,我也顺便总结一下。

首先,构建XML文档对象,存入表单数据,代码如下。
/* data参数为表单数据组成的对象,dataToSend为待发送给后端的数据 */

var dataToSend = document.implementation.createDocument("", "formdata", null);
var tempData = dataToSend.documentElement;
for (var key in data) {
if (data.hasOwnProperty(key)) {
var keyElement = doc.createElement(key);
keyElement.appendChild(doc.createTextNode(data[key]));
tempData.appendChild(keyElement);
}
}

/*
xml文档格式示意:
<formdata>
<key1> value1 </key1>
<key2> value2 </key2>
</formdata>
*/


之后,与
multipart/form-data
一样,直接发送数据,不需设置
Content-Type

req.send(dataToSend);


小结

multipart/form-data
text/xml
不需要设置请求头的
Content-Type


关于
method
,以上都是
POST
方式,若是
GET
方式是没有请求数据体的,数据直接加在URL后面;


附:接收请求时的解析方式

text/xml:用
responseXML


application/json:需要先JSON化,
JSON.parse( responseText
)


其他:就直接用
responseText



jQuery 方式


application/x-www-form-urlencoded

jQuery中默认的表单提交方式,与XMLHttpRequest不同的地方在于:数据的URL方式编码,由jQuery来做,只需要在
$.ajax({})
参数中设置
processData
= true
(这也是默认,可省略)。

代码如下。
/* dataToSend为Object类型的表单数据,否则jQuery会抛出异常 */

$.ajax({
method: 'POST',
url: '...',
data: dataToSend,

contentType: 'application/x-www-form-urlencoded',    // 可省略
processData: true,        // 可省略

success: function() {...}
});


注意:若采用
GET
方式,则将
method
改为GET即可,不需要在url后面加上数据。


multipart/form-data

这种MIME类型的提交方式,适合用于上传文件。

首先,对表单数据构建成FormData的HTML5对象,代码如下。
/* dataToSend 是FormData对象,可直接作为数据传输到后端 */

var dataToSend= new FormData();      // HTML5对象, IE11以下不支持
for (var key in data) {
if (data.hasOwnProperty(key)) {
dataToSend.append(key, data[key]);
}
}


之后,用
$.ajax()
方法传输数据。注意:
processData
contentType
必须设定为
false
,前者是因为避免
FormData
对象被转换成URL编码,后者则是因为需要靠浏览器添加
multipart/form-data
类型的boundary。
$.ajax({
method: 'POST',
url: '...',
data: dataToSend,          // dataToSend 是FormData对象

contentType: false,        // contentType 必须设置为false
processData: false,        // processData 必须设置为false

success: function() { ... }
});


text/plain

用该类型提交,则直接传输字符串。
$.ajax({
method: 'POST',
url: '...',
data: dataToSend,

contentType: 'text/plain',
processData: false,        // processData 设置为false则不会转换成URL编码

success: function() { ... }
});


application/json

用该类型提交,则传输JSON字符串,所以要用函数
JSON.stringify()
处理表单数据。
/* data 为表单Object类型的数据 */

dataToSend = JSON.stringify(data);

$.ajax({
method: 'POST',
url: '...',
data: dataToSend,

contentType: 'application/json',
processData: false,        // processData 设置为false则不会转换成URL编码

success: function() { ... }
});


注意:若后端也返回JSON字符串时,
success
回调函数里接受到的数据参数仍为字符串,需要转换成
Object
类型。(而Angular不需要)
$.ajax({
...
success: function(data) {
var jsonData = JSON.parse(data);
...
}
});


text/xml

首先,构建XML文档对象,存入表单数据,代码如下。
/* data参数为表单数据组成的对象,dataToSend为待发送给后端的数据 */

var dataToSend = document.implementation.createDocument("", "formdata", null);
var tempData = dataToSend.documentElement;
for (var key in data) {
if (data.hasOwnProperty(key)) {
var keyElement = doc.createElement(key);
keyElement.appendChild(doc.createTextNode(data[key]));
tempData.appendChild(keyElement);
}
}

/*
xml文档格式示意:
<formdata>
<key1> value1 </key1>
<key2> value2 </key2>
</formdata>
*/


之后,发送数据
dataToSend
,代码如下。
$.ajax({
method: 'POST',
url: '...',
data: dataToSend,

contentType: false,    // contentType 可设为false也可写成具体的'text/xml'等
processData: false,    // processData 必须设为false

success: function() { ... }
});


AngularJS 方式


application/x-www-form-urlencoded

用这种MIME类型提交表单数据,则需要对表单数据进行URL编码,用
$.param(data)
函数,代码如下。
$http({
method: 'POST',
url: '...',
data: $.param(dataToSend),
headers: { 'Content-Type': 'application/x-www-form-urlencoded'}
).success(...);


multipart/form-data

首先,该类型如果要上传文件,那么Angular为了获取文件,推荐写成指令。代码如下。
.directive("fileReader", [function () {
return {
restrict: 'AE',
scope: {
fileReader: "="        // HTML中的file-reader作为存放文件对象的变量
},
link: function (scope, element) {
element.bind("change", function (changeEvent) {
scope.$apply(function () {
scope.fileReader = changeEvent.target.files[0];
});
});
}
}
}])

/* HTML结构如下 */
<input type="file" name="key1" file-reader="formData.file[1]">


然后,需要用
FormData
对象来包装表单数据并传输,建议写在
$http
服务的
transformRequest
选项中;另外,与jQuery类似其中的请求头
Content-Type
要设置为
undefined
。代码如下。
$http({
method: 'POST',
url: '...',
data: dataToSend,
headers: {
'Content-Type': undefined               // 必须设置为undefined
},

transformRequest: function(data) {
var tempFormData = new FormData();      // HTML5对象, IE11以下不支持
for (var key in data) {
if (data.hasOwnProperty(key)) {
tempFormData.append(key, data[key]);
}
}
return tempFormData;
}
}).success(...)


text/plain

以字符串的方式提交表单数据,代码如下。
$http({
method: 'POST',
url: '...',
data: dataToSend,
headers: {
'Content-Type': 'text/plain'
}).success(...)


application/json

以JSON字符串的方式提交表单数据,用
JSON.stringify()
函数转换,代码如下。
$http({
method: 'POST',
url: '...',
data: JSON.stringify(dataToSend),
headers: {
'Content-Type': 'application/json'
}).success(...)


注意:但是在
success
函数里接受到的参数,就是
Object
对象,不需要和jQuery一样用
JSON.parse()
转换。


text/xml

multipart/form-data
类似,在
transformRequest
中构建
XML
Document
,请求头中的
Content-Type
设置为
undefined
text/xml
等,代码如下。
$http({
method: 'POST',
url: '...',
data: dataToSend,
headers: {
'Content-Type': undefined               // 设置为undefined或'text/xml'等
},

transformRequest: function(data) {
var doc = document.implementation.createDocument("", "formdata", null);
var tempData = doc.documentElement;
for (var key in data) {
if (data.hasOwnProperty(key)) {
var keyElement = doc.createElement(key);
keyElement.appendChild(doc.createTextNode(data[key]));
tempData.appendChild(keyElement);
}
}
return doc;
}
}).success(...)


附:GET方式提交表单数据

Angular用GET方式提交表单数据,应该用
$http
服务的
params
而不是
data
来传数据,
params
可以直接传入
Object
类型数据,代码如下。
$http({
method: 'GET',
url: '...',
params: dataToSend
}).success(...)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: