Ajax,Fetch,Axios网络请求的简单分析及对比,只是简单的对比,并不是很深入,希望可以帮助到你
Ajax是异步的javascript和XML,Ajax不是一个技术,而是技术的统称,是一个概念模型,它包括了很多技术,并不是特指一个技术,它的重要特性就是实现页面的局部刷新,Ajax是一种思想,XMLHttpRequest只是实现Ajax的一种方式,面试中最容易面试到的就是手撕Ajax请求代码,下面展示三个Ajax不同情况下的代码,其实都大同小异,只是我分开写了而已
请求发送出去后,客户端需要接收服务器响应回来的数据,xhr对象中有一些属性,它们存储着服务端返回来的一些数据信息,如下表所示
function ajax(url) {
//创建ajax对象(声明一个变量,用来实例化XMLHttpRequest对象)
const xhr = new XMLHttpRequest();
//使用ajax下的open方法打开接口,表示创建一个请求,
// 参数分别是 get / post请求 接口地址 是否异步(true为异步请求,false为同步请求)
xhr.open("get", url, false);
// xhr对象可以绑定一个 onreadystatechange 事件,每当 readyState 属性发生改变,都会触发该事件,因此,该事件在一次请求中会被多次触发
xhr.onreadystatechange = function () {
// 判断是否已接收所有响应
// readyState码:0:请求未初始化;1:服务连接已建立; 2:请求已接收; 3:请求处理中;4:请求已完成,切响应已就绪。
if (xhr.readyState === 4) {
// //status状态码:2XX:成功处理请求;3XXX:需要重新定向,浏览器直接跳转;4XXX:客户端请求错误;5XXX:服务端错误
if (xhr.status === 200) {
// 从服务器端返回文本。
console.log(xhr.responseText);
}
}
};
// 用send方法发送请求,send() 方法接收一个参数
// 光调用了 open() 方法还不够,它只是创建了一个请求,但还没有发送请求,因此我们还要调用xhr对象上的另一个方法,即 send() 方法,表示将请求发送给目标URL
//如果上面创建的是get请求,因此send()方法无需传参或者写null
xhr.send();
}
// 调用
ajax("这里写接口地址的链接");
function ajax(url) {
//创建ajax对象(声明一个变量,用来实例化XMLHttpRequest对象)
const xhr = new XMLHttpRequest();
//使用ajax下的open方法打开接口,表示创建一个请求,
// 参数分别是 get / post请求 接口地址 是否异步(true为异步请求,false为同步请求)
xhr.open("post", url, false);
//post方法必需,设置请求头
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
// xhr对象可以绑定一个 onreadystatechange 事件,每当 readyState 属性发生改变,都会触发该事件,因此,该事件在一次请求中会被多次触发
xhr.onreadystatechange = function () {
// 判断是否已接收所有响应
// readyState码:0:请求未初始化;1:服务连接已建立; 2:请求已接收; 3:请求处理中;4:请求已完成,切响应已就绪。
if (xhr.readyState === 4) {
// //status状态码:2XX:成功处理请求;3XXX:需要重新定向,浏览器直接跳转;4XXX:客户端请求错误;5XXX:服务端错误
if (xhr.status === 200) {
// 从服务器端返回文本。
console.log(xhr.responseText);
}
}
};
const postData = {
userName: "小明",
passWord: "123456",
};
// 用send方法发送请求,send() 方法接收一个参数
// 光调用了 open() 方法还不够,它只是创建了一个请求,但还没有发送请求,因此我们还要调用xhr对象上的另一个方法,即 send() 方法,表示将请求发送给目标URL
//如果上面创建的是get请求,因此send()方法无需传参
//发送请求,把对象参数用JSON方法转为字符串参数
xhr.send(JSON.stringify(postData));
}
// 调用
ajax("这里写接口地址的链接");
function ajax(url) {
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
// 这里的 status 可以适当修改
if (xhr.status === 200) {
resolve(
// 将得到 responseText 转换为JSON格式数据
JSON.parse(xhr.responseText)
);
} else if (xhr.status === 404) {
reject(new Error("404 not found"));
}
}
};
xhr.send(null);
});
return p;
}
//调用
// 调用
ajax("这里写接口地址的链接")
.then((res) => console.log(res))
.catch((err) => console.err(err));
function ajax(option) {
const p = new Promise((resolve, reject) => {
// 这个方法主要是将对象形式的参数变成用&符号链接的字符串,方便传参使用
// 例如 let obj={a:100,b:200} 通过该方法可以变成 a=100&b=100
function objTostring(obj) {
// 先判断参数是不是对象
if (Object.prototype.toString.call(obj) === '[object Object]') {
let arr = [];
for (let i in obj) {
arr.push(i + '=' + obj[i])
}
return arr.join('&')
} else {
throw new Error('参数应该是对象')
}
}
const xhr = new XMLHttpRequest();
//1、 配置请求方式
option.type = option.type || 'get';//兼容,如果option中的type有值就用option中的,没有就用get
//2、配置接口地址,不可以省略
if (!option.url) {
throw new Error('接口地址不能为空')
}
// 3、配置数据格式(get请求在地址栏拼接 post请求设置请求头)
// 判断参数是否存在+get请求
if (option.data && option.type === 'get') {
option.url += '?' + objTostring(option.data)
}
//4、判断是否异步
if (option.async === 'false' || option === false) {
option.async = false//同步
} else {
option.async = true//异步
}
xhr.open(option.type, option.url, option.async);
// 判断参数是否存在+post请求
if (option.data && option.type === 'post') {
// 配置请求头,post请求必须写请求头
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// post请求进行传参(send传参)
xhr.send(objTostring(option.data))
} else {
xhr.send();
}
// 5、同步异步获取数据
if (option.async) {//option.async存在就是异步
xhr.onload = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log('异步', xhr.responseText)
option.success && typeof option.success === 'function' && resolve(option.success(xhr.responseText))
} else {
option.error && typeof option.error === 'function' && reject(option.error('状态码有误!'))
}
}
} else {
// 同步
console.log('同步', xhr.responseText)
}
})
}
// ajax调用
ajax({
type: 'get',//可省略不写, 默认get,可设置成post
url: 'https://www.fastmock.site/mock/33b2c932b3482797c85219d76a110350/api/home/echarts1',//不可省略
data: {//传的参数,没有的话可省略不写
},
async: true,//可省略不写,默认为异步(true),可设置成同步(false)或者'false'
success: function (res) {//获取数据成功后的回调函数
// 我们在这里获取到数据后就可以进行页面的数据渲染了
console.log('success', res)
},
error: function (err) {//获取数据失败后的回调函数
throw new Error(err)
}
})
Fetch是ES6出现的,它使用了ES6提出的Promise对象,是XMLHttpRequest的替代品,Fetch是一个原生的API,是真实存在的,是基于Promise实现的(链式调用)。
Fetch的特点:
使用Promis,不使用回调函数式(回调地域)
采用模块化设计,rep,res分开的,比较友好
网络性能更好
function ajaxFetch(url) {
fetch(url).then(res => res.json()).then(data => {
console.log(data)
})
ajaxFetch(url)
}
Axios是随着Vue的兴起被广泛使用的,目前来说,绝大多数的Vue项目中的网络请求都是利用Axios发起的,他并不是一个思想或者原生的API,而是一个封装库,Axios是基于Promise封装的网络请求库,是基于XHR的二次封装,可以用在浏览器和 node.js 中。
Axios的特点:
支持Promise的APi
自动转换json数据
使用时需要引入axios
axios可以用在浏览器和 node.js 中是因为,它会自动判断当前环境是什么,如果是浏览器,就会基于XMLHttpRequests实现axios。如果是node.js环境,就会基于node内置核心模块http实现axios
简单来说,axios的基本原理是:
1、axios还是属于 XMLHttpRequest, 因此需要实现一个ajax。或者基于http 。
2、还需要一个promise对象来对结果进行处理。
这里只展示请求,关于拦截器可看axios官网
// 方式一 将参数直接写在url中
axios.get('/geturl?id=12345')
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
// 第二种方式 将参数直接写在params中
axios.get('/geturl', {
params: {
id: 12345
}
})
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
axios.post('/geturl', {
id: 12345//注意!这里和get请求传参的第二种方式很像,但是不一样,需要仔细看
})
.then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err)
})
axios是通过Promise实现对ajax技术的一种封装,axios比ajax更好用更安全。
简单来说就是ajax技术实现了局部数据的刷新,axios实现了对ajax的封装;总结就是axios是ajax,ajax不止axios。
请求方式 | 特点 |
---|---|
Ajax | 是一种技术统称,主要通过XHR实现网络请求 |
Fetch | 是一个具体的API,基于Promise实现网络请求 |
Axios | 是一个封装库,基于Promise对XHR封装 |