跳到主要内容

AJAX

XMLHttpRequest

const xhr = new XMLHttpRequest();

// 请求方式,路径,是否异步
xhr.open('GET', 'https://www.easy-mock.com/mock/5c94518744e20f337dc3c58c/test/zgh/zghivan', false);

// 设置xhrt对象不发送数据到服务器
xhr.send(null);

if (xhr.status == 200) {
const data = xhr.responseText;
document.getElementById('contont').innerText = data;
}

封装 ajax

调用方式:

ajax({
type: 'GET',
url: 'http://localhost:3000/posts',
timeout: 5000,
data: {},
success: res => {
console.log('success', res);
},
error: err => {
console.log('error', err);
}
});

实现代码:

const ajax = options => {
const objToString = data => {
// 加个时间戳,避免缓存
data.t = new Dat().getTime();
let res = [];
for (let key in data) {
// url里不能有中文
res.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
return res.join('&');
};

let str = objToString(options.data || {});

// 1. 创建一个xhr对象
var xhr, timer;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
// 兼容IE
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}

// 2. 设置请求方式,路径,是否异步
if (options.type.toUpperCase() === 'GET') {
xhr.open(options.type, options.url + '?=' + str, options.async || true);
xhr.send(null);
}

if (options.type.toUpperCase() === 'POST') {
xhr.open(options.type, options.url, options.async || true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(options.data);
}

// 3. 监听状态改变
xhr.onreadystatechange = function () {
clearInterval(timer);
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
options.success(xhr.responseText);
} else {
options.error(xhr.responseText);
}
}
};

// 4. 设置超时时间
if (options.timeout) {
timer = setInterval(() => {
xhr.abort(); // 中断请求
clearInterval(timer);
}, options.timeout);
}
};

准备 json 数据,使用 json-server 搭建一个本地服务器,开始验证。

jquery 中的 ajax

<button id="btn">click!</button>

<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
$('#btn').click(function me() {
$.ajax({
url: 'https://www.easy-mock.com/mock/5c94518744e20f337dc3c58c/test/zgh/zghivan',
type: 'get',
dataType: 'json',
async: true,
// post请求可以传递数据
// data: {id : 1},
success: function (data) {
console.log(data);
},
error: function () {
console.log('error');
}
});
});
</script>

jquery 中的$.ajax()常用参数:

参数说明
url请求地址
async是否异步
data发送到服务器的数据
contentType发送到服务器的数据编码类型
type请求类型
success请求成功的回调函数
error请求失败的回调函数

若为 get 请求可直接在 url 中使用?拼接

fetch

fetch('http://localhost:3000/posts')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.log(err));

axios

基于 Promise 可以用于浏览器和 node.js 的网络请求库

  • 作用于浏览器端和 node.js
  • 在服务端使用 node.js 的 http 模块,而在浏览器端使用 XMLHttpRequests

特性

  • 从浏览器创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 超时处理
  • 查询参数序列化支持嵌套项处理
  • 自动将请求体序列化为:
    • JSON (application/json)
    • Multipart / FormData (multipart/form-data)
    • URL encoded form (application/x-www-form-urlencoded)
  • 将 HTML Form 转换成 JSON 进行请求
  • 自动转换 JSON 数据
  • 获取浏览器和 node.js 的请求进度,并提供额外的信息(速度、剩余时间)
  • 为 node.js 设置带宽限制
  • 兼容符合规范的 FormData 和 Blob(包括 node.js)
  • 客户端支持防御 XSRF

Content-Type

Axios 请求头中的Content-Type常见的有三种:

  • Content-Type: application/json
  • Content-Type: application/x-www-form-urlencoded
  • Content-Type: multipart/form-data

请求头配置:

headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
  1. application/json是默认的方式,声明了将请求体中的数据以 json 字符串的格式传给后端。
  2. application/x-www-form-urlencoded声明了请求体中的数据会以键值对(普通表单形式)发送到后端,这种类型是 Ajax 默认的。 请求体一般是 json 对象,可以使用qs库将对象转为 url 参数形式。

qs 能将对象和 url 中的参数互相转换。

官方文档 urlencoded

import qs from 'qs';

const url = 'user=zgh&password=123';
// 转为对象
console.log(qs.parse(url)); // { user: 'zgh', password: '123' }

const obj = { name: 'zgh', age: 23 };
// 转为url参数形式
console.log(qs.stringify(obj)); // 'name=zgh&age=23'
提示

最新版本中,已实现了自动序列化。当请求头中的 content-typeapplication/x-www-form-urlencoded 时,Axios 将自动地将普通对象序列化成 urlencoded 的格式。

  1. multipart/form-data一般用来传输文件,数据为二进制格式,也可为键值对格式

官方文档 form-data

const fileData = new FormData();
fileData.append('file', file);
fileData.append('name', 'zgh');

// 如果想传输文件数组
fileData.append('files', file1);
fileData.append('files', file2);
fileData.append('files', file3);
提示

从 v0.27.0 版本开始,当请求头中的 Content-Typemultipart/form-data 时,Axios 支持自动地将普通对象序列化成一个 FormData 对象