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

用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);

小结

  1. multipart/form-datatext/xml不需要设置请求头的Content-Type
  2. 关于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()方法传输数据。
注意:processDatacontentType必须设定为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设置为undefinedtext/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(...)

COPY FROM https://segmentfault.com/a/1190000004982390
时间: 2024-10-11 23:25:29

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

tp5中ajax方式提交表单

用ajax提交表单,迅速,快捷,实现页面无刷新提交表单. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ajax批删</title> </head> <body> <center> <table> <tr> <td>姓名</t

ASP.NET MVC 网站开发总结(五)——Ajax异步提交表单之检查验证码

首先提出一个问题:在做网站开发的时候,用到了验证码来防止恶意提交表单,那么要如何实现当验证码错误时,只是刷新一下验证码,而其它填写的信息不改变? 先说一下为什么有这个需求:以提交注册信息页面为例,一般注册都需要用户填一个验证码信息(防止机器恶意注册),并且这个验证码会提交到后台去进行比对,若是错了则不会检查其他提交信息而直接返回浏览器端提示验证码错误.若是简单地用form表单直接将数据提交到指定的url,当验证码填写错误的信息返回浏览器端的时候,不可避免整个页面都会重新刷新一次,这是用户所不想要

post方式get方式提交表单的主要区别

post方式get方式提交表单的主要区别: 使用表单给网站后台提交数有种两种方式,一种是post方式,一种是get方式,下面就简单介绍一下这两种方式的主要区别. 一.post方式: 此方式一般用于传递较大的数据,在数据传递之前会有打包操作,所以可能会造成数据传递数据相对较慢的情况,不过传输的数据都能够被正确的解析,不会出现类似于中文乱码的状况. 二.get方式: 通过url链接传递数据,和post相比传输的数据量较小,而且传递的数据必须是ASCCI码值范围内的,因此传递中文的时候可能会出现乱码情

使用ajax异步提交表单

虽然这篇文章的标题是提交表单,但是主要的难点在于使用ajax提交文本域的内容, 在工作中的经常会需要ajax跨域的问题,通常的需求使用jsonp就可以得到解决,但是当前项目中有一个图片服务器,客户端需要直接上传图片到图片服务器中,这就产生了一个跨域post提交文件的问题,很显然jquery本身jsonp只支持get方式的异步提交肯定是不行 其中也尝试过使用ifrmae的方法来提交数据,在网上有,但是效果不理想,并且也很复杂的样子,最后选择出了jquery.from.js 这个插件,可以实现异步的

Asp.net Mvc Ajax.BeginForm提交表单

之前Mvc中一直用Html.BeginForm提交表单,即如下: @using (Html.BeginForm("Add", "News", FormMethod.Post, new { enctype = "multipart/form-data" })) { <table> <tr> <td><span style="color:red">*</span><

jQuery通过AJAX快速提交表单数据

当表单数据项很多时,手动获取表单项的值将变得效率低下,结合jQuery提供的函数serialize(),我们可以实现快速获取数据并提交表单数据. 请看下面的表单: <form id="fm"> <table> <tr> <td>姓名</td> <td> <input type="text" name="name" /> </td> </tr>

spring-boot restful put方式提交表单

使用spring-boot 做接口,如果按restful的路由形式想使用put方式进行表单提交,第一个参数应该为文件参数,代码如下: @PutMapping("/http-put") public IbaseWorkResult httpPut(@RequestParam("file") MultipartFile multipartFile, @RequestParam("project_id") Integer project_id) { S

调用submit()方式提交表单

今天在看高级程序设计时看到的这样一段话: 在以调用submit()方法的形式提交表单时,不会触发submit事件 写了一个小例子做了下测试,的确如此: <form id="fm" action="http://www.baidu.com"> <input type="text" id="txt"> <button id="btn" type="submit"

使用post方式提交表单如何获取图片数据及其他文本参数[NodeJS]

当POST方式提交包含图片的表单时,如上传图片时,需要在<form>字段需要添加参数enctype="multipart/form-data",表明以二进制方式传输数据.假如表单中包含其他文本参数,如用户名username,用常规方式是无法获取post参数的,如: <html> <head> <meta http-equiv="Content-Type" content="text/html" chars