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

用Ajax方式提交,决定编码类型的是请求头中 Content-Type ,不同值对应不同提交处理方式。

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

# XMLHttpRequest 方式

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

application/x-www-form-urlencoded

这种Content-Type要求数据按照key1=value1&key2=value2的格式发送给后端,且其中的特殊字符需要转义成%HH的形式。其中HH表示该字符的十六进制ASCII码。例如,空格字符的ASCII码是32,所以它被转义成%20。

首先,需要用 encodeURIComponent() 函数编码表单数据,代码如下。

req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

/* 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

多用来提交文件,可采用H5的FormData对象来构建提交的数据。

现代浏览器都支持,IE11以下不支持,不支持的可以使用ajaxForm之类的jquery的文件提交插件。

/* data参数为表单数据组成的对象,dataToSend为待发送给后端的数据 */

var dataToSend = new FormData();   
for (var key in data) {
    if (data.hasOwnProperty(key)) {
        dataToSend.append(key, data[key]);
    }
}

// dataToSend就是FormData对象,可直接传给后端
//接着,直接发送给后端,注意这种类型的发送方式,
//不需设置请求头部的Content-Type,应交给浏览器来处理(设定Boundary等工作)。

req.send(dataToSend);

text/plain

如果请求头部没有设定Content-Type,且数据既不是FormData也不是XML Document,则Content-Type默认text/plain。

//这种方式的代码很简单,直接发送字符串即可。
req.send('xxxx');

application/json

JSON格式的数据,后端和移动端都很方便处理,用这种MIME类型时,需要将数据对象转换成JSON串。 首先,转换数据成JSON串;然后,设定请求头部的Content-Type,就可以发数据了。

/* data参数为表单数据组成的对象 */

req.send( JSON.stringify(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>
*/
//之后,与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,        // 可省略 对data参数进行序列化处理
    success: function() {...}
});
// 注意:若采用GET方式,则将method改为GET即可,不需要在url后面加上数据。

multipart/form-data

/* 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,       
    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,vue使用的axios也不需要)

$.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() { ... }
});

$ajax参数详解 (opens new window)

# axios方式

先系统的默认axios的content-type的方式为application/x-www-form-urlencoded

import axios from 'axios'
import VueAxios from 'vue-axios'

axios.defaults.baseURL='http://xxxxx/xxx'
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
Vue.prototype.$axios = axios;

# post

  //post请求:
  //需要安装qs模块
  let postData = this.$qs.stringify({
            name: that.name,
            phone:that.tele,
            password:md5pass,
        
        });
    this.$axios.post('/user/register', 
        postData
        )
//JSON格式传
 let postData={  
				bank:that.bank,
				bankAccount:that.banknumber,
				name:that.company
           }

let config = {
	headers: {'Content-Type': 'application/json'}
}

this.$axios.post('/invoice/insertInvoices',
    postData,config
    )

总结: get请求的数据一般放在地址栏里,以axios为例,可拼接在api后面也可以写在parsms里['/get12?id=19',{params:obj}]都在query string parameters。而post可能在formdata里(www格式和formdata文件时),也可能周期request payload中(application/json时)

# 关于multipart/form-data设置

对于multipart/form-data设置,博客上有要是用和不适用两种,通过试验,结论如下:

  • 如果是form表单提交,则必须设置。
  • 如果使用axios,则可以不设置,而且手动设置成其他类型,接口依旧能处理,且请求体Content-Type仍然是multipart/form-data
  • 使用了element插件,自己手动设置了headers content-type:multipart/form-data,会出错
  • 上传图片(Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0iJj0hLz7qx5IKiM) boundary:自己设置contenttype在element就会没有
  • 使用node服务器测试的,在java下也可以,其他未知!
  • 当请求data未设置,axios会删除请求的content-type;
//npm下axios的源码中,当未设置requestData的时候会删掉Content-Type的设置

// Add headers to the request
if ('setRequestHeader' in request) {
    utils.forEach(requestHeaders, function setRequestHeader(val, key) {
    if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
      // Remove Content-Type if data is undefined
      delete requestHeaders[key];
    } else {
      // Otherwise add header to the request
      request.setRequestHeader(key, val);
    }
  });
}
// 假如后端非要这个熟悉的话,解决办法
service.interceptors.request.use(
    config => {
        config.data = JSON.stringify(config.data);
        config.headers['Authorization'] = getToken();
 
        config.data = true
        config.headers[ 'Content-Type'] = "application/json;charset=utf-8";
 
        return config;
    },
    error => {
        return Promise.reject();
    }

# contType在请求的时候设置

      const data ={
        visionId,
        groupId:'2',
        orgCategory:'0'
      }
      var tempArr =[]
      for (var key in data) {
        if (data.hasOwnProperty(key)) {
            tempArr.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
        }
    }
    
    var dataToSend = tempArr.join('&');   
	
    this.cloudConfig.headers = {}
    this.cloudConfig.headers['Content-Type'] ='application/x-www-form-urlencoded'
    return this.http.Post(`/xxx`,dataToSend,this.cloudConfig)
	//或者不需要配置cloudConfig,直接加载后面也可以
	return this.http.Post(`/xxx?visionId=${visionId}&groupId='2'&orgCategory=${orgCategory}`,null,this.cloudConfig)
最后更新: 1/20/2024, 8:58:17 PM