下面内容是关于 Query String Parameters
、Form Data
、 Request Payload
三种格式的区别。主要是因为 Content-Type
与请求方式 method
不同,导致传递的数据格式不同。
Content-Type: [media-type];[charset];boundary
原生 ajax 请求默认 Content-Type: text/plain;charset=UTF-8
常见的媒体格式:
请求参数格式
*1. Query String Parameters
格式: ?key=value&key=value
参数会以 url string 的形式进行传递,即?后的字符串则为其请求参数,并以&作为分隔符。常用在 GET 请求方式时使用。 其他请求方式也可以使用,拼接在接口地址 `url?` 后面。
![Query String Parameters](https://raw.githubusercontent.com/wqjiao/Points-Issues/master/assets/QueryStringParameter.png)
*2. Form Data
格式:key=value&key=value
键值对形式
- 当
Content-type
为application/x-www-form-urlencoded;charset=utf-8
时,参数会以Form Data
的形式(数据为 String 键值对格式)传递给接口,并且不会显示在接口 url 上。
let data = {
username: 'wqjiao',
password: '111111',
}
xhr.send(QS.stringify(data));
- 对表单提交和文件上传时做特殊处理,需要使用
new FormData()
方法处理后传递给接口,Content-type
为multipart/form-data; boundary=----WebKitFormBoundarys9jOoKcA1Kwn9sYS
格式。
const formData = new FormData();
formData.append('label', 'ID_photo-front');
formData.append('subId', 'fa6abb94000a4ba1b19a43e60eba1516');
formData.append('file', fileList[0]);
fetch('http://192.168.1.128:5022/tool/file/upload', {
method: 'POST',
headers: {
'Authorization': '89199cf3294520765904d47c2c570c1b',
},
body: formData,
cridentials: 'include',
mode: 'no-cors',
processData: false,
cache: false,
contentType: false,
});
-
补充说明
服务器为什么会对表单提交和文件上传做特殊处理,因为表单提交数据是名值对的方式,且Content-Type为application/x-www-form-urlencoded,而文件上传服务器需要特殊处理,普通的post请求(Content-Type不是application/x-www-form-urlencoded)数据格式不固定,不一定是名值对的方式,所以服务器无法知道具体的处理方式,所以只能通过获取原始数据流的方式来进行解析。
- processData: false --> 因为 data 值是
formdata
对象,不需要对数据做处理。 - cache: false --> 上传文件不需要缓存。
- contentType: false --> 因为是由
<form>
表单构造的FormData
对象,且已经声明了属性enctype="multipart/form-data"
,所以这里设置为 false。 - xhrFields: { withCredentials: true }, 跨域请求设置
*3. Request Payload
格式:{key: value, key: value}
(后端经过反序列化得到对象)
当 `Content-type` 为 `application/json;charset=utf-8` 时,参数会以 `Request Payload` 的形式(数据为 json 格式)传递给接口,并且不会显示在接口 url 上。
```js
let data = {
username: 'wqjiao',
password: '111111',
}
xhr.send(Qs.stringify(data));
```
let Ajax = {
get: function (url, fn) {
// XMLHttpRequest对象用于在后台与服务器交换数据
let xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function () {
// readyState == 4说明请求已完成
if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304) {
// 从服务器获得数据
fn.call(this, xhr.responseText);
}
};
xhr.send();
},
// data 应为'a=a1&b=b1'这种字符串格式,在jq里如果data为对象会自动将对象转成这种字符串格式
post: function (url, data, fn) {
let xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
// xhr.open("POST", '/response.json', true);
xhr.setRequestHeader('Accept', 'application/json')
xhr.setRequestHeader('Authorization', 'bb850ec168d55eedcb0b47ac4e7c9d6b')
// 添加http头,发送信息至服务器时内容编码类型
xhr.setRequestHeader("Content-Type", "application/json");
// xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
fn.call(this, xhr.responseText);
}
};
// application/json 格式:{key: value, key: value}
xhr.send(JSON.stringify(data));
// application/x-www-form-urlencoded 格式:key=value&key=value
// xhr.send(Qs.stringify(data));
}
}
new FormData(form)
-
获取数据
- 获取一个控件的 value :
formData.get('name');
- 获取一组控件 name 为 username 的 values,返回数组 :
formData.getAll('username');
- 获取一个控件的 value :
- 添加数据
formData.append('username', 'qq');
- 设置修改数据
formData.set("username", 'wqjiao');
注意:如果
formData
中不存在 username 字段,那么,js不会报错,而是直接新增当前键值对。 - 判断是否存在该数据,返回 Boolean 类型
formData.has('username');
- 删除某数据
formData.delete('username');
- 返回所有的键值对:
formData.entries()
formData.entries()
方法返回一个 iterator 对象 ,此对象可以遍历访问formData
中的键值对。其中键值对的 key 是一个 USVString 对象;value 是一个 USVString , 或者 Blob 对象。 -
实例
<form id="myForm"> <input type="text" name="name" placeholder="请输入你的名字" /> <input type="password" name="password" placeholder="请输入你的密码" /> <input type="text" name="n1" /> <input type="text" name="n1" /> <input type="submit" id="submitBtn" value="提交" /> </form> <script> // 表单初始化 let form = document.getElementById('myForm'); let submitBtn = document.getElementById('submitBtn'); submitBtn.addEventListener('click', function (e) { e.preventDefault(); let formData = new FormData(form); // 获取数据 let name = formData.get('name'); let arr = formData.getAll('n1'); // 添加数据 formData.append('username', 'wqjiao'); // 判断是否存在 name 为 deletename if (formData.has('deletename')) { // 修改数据 formData.set("deletename", '123456'); } // 删除数据 formData.delete('password'); // 返回所有的数据,遇到重复的 name,保留最新的值 let data = {}; for(let name of formData.entries()) { if (name) { data[name[0]] = name[1]; } } console.log(name, arr, data); // 请求接口 let xhr = new XMLHttpRequest(); xhr.open('POST', 'response.json', true); xhr.send(formData); }, false); </script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。