ToB企服应用市场:ToB评测及商务社交产业平台
标题:
Ajax和Axios实现
[打印本页]
作者:
怀念夏天
时间:
2024-9-16 08:13
标题:
Ajax和Axios实现
实现原生Ajax
简介
AJAX = 异步 JavaScript 和 XML。
AJAX 是一种用于创建快速动态网页的技能。
通过在后台与服务器进行少量数据互换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的环境下,对网页的某部门进行更新。
详细先容请移步AJAX 简介 | 菜鸟教程
最简版本
function myAjax(method, url) {
const xhr = new XMLHttpRequest()
xhr.open(method, url)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 304) {
console.log(xhr.responseText);
} else {
console.log(new Error(xhr.statusText));
}
}
}
xhr.send()
}
复制代码
带promis版本
function myAjax(method, url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open(method, url)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 304) {
resolve(xhr.responseText)
} else {
resolve(new Error(xhr.statusText))
}
}
}
xhr.send()
})
}
复制代码
实现Axios
在平时写项目中大部门都会用到axios,但是对axios的实现却没怎么相识过,本日趁着休息,用js实现axios
简介
Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它利用原生 node.js http 模块, 而在客户端 (浏览端) 则利用 XMLHttpRequests。
详细详细先容请移步起步 | Axios中文文档 | Axios中文网
这里实现出几个主要的方法,包罗
post
请求方法,
create
配置方法,以及
拦截器
的方法。
1.post方法
实现前先写一个类,在类的原型对象上进行方法的实现
function cAxios() {
}
复制代码
实现时注意两点:
axios的post的方法返回的是一个promise对象
axios的post的方法的data参数是一个对象,而原生的XMLHttpRequest对象的send方法参数是string
所以需要在send方法里面把data参数转化为JSON格式的字符串
cAxios.prototype.post = function (method, url, data) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open(method, url)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 304) {
resolve(xhr.responseText)
} else {
reject(new Error(reject.statusText))
}
}
}
xhr.send(JSON.stringify(data))
})
}
复制代码
get方法也是一样的,不再形貌
2.create方法
axios.create(config)
根据指定配置创建一个新的 axios, 也就就每个新 axios 都有自己的配置(主要是请求头的配置)
新 axios 只是没有取消请求和批量发请求的方法, 其它所有语法都是同等的
这里的实现只是列举了headers和baseUrl这两个属性
cAxios.prototype.create = function (obj) {
let axios = new cAxios()
axios.headers = obj.headers;
axios.baseUrl = obj.baseUrl;
return axios
}
复制代码
所以假如我们设置请求头以后,调用post方法需要带上这些参数,因此post方法需要修改
起首需要写一个方法来配置请求头
function setHeaders(xhr, headers){
for(let key in headers) {
xhr.setquestHeader(key, headers[key])
}
}
复制代码
在post方法中,在ajax发送请求之前调用即可
setHeaders(xhr, this.headers)
复制代码
3.拦截器
axios的拦截器分为请求拦截器和响应拦截器
寄义:在请求或响应被 then 或 catch 处理前拦截它们。
官网实例
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
});
复制代码
这里可以看到interceptors是一个对象,里面包含request和response属性
本文实现不考虑use
我们需要在类里面实现一下interceptors
this.interceptors = {
request(fn) {
_this.saveReqFn.push(fn)
},
response(fn) {
_this.saveResFn.push(fn)
}
}
复制代码
假如我们想在外边调用请求拦截器或者响应拦截器,需要传递一个回调函数作为拦截器的参数
所以在我们这里我们需要把这个回调函数生存下来(考虑到有多个拦截器,所以我们接纳数组生存)。
同时我们也要写一个data用于存放请求时的数据(由于在请求拦截器的回调函数中,有一个config参数,它包含着请求的数据)
function cAxios() {
// 保存请求拦截器中的回调函数
this.saveReqFn = []
// 保存响应拦截器中的回调函数
this.saveResFn = []
// 保存请求的数据
this.data = []
let _this = this
this.interceptors = {
request(fn) {
_this.saveReqFn.push(fn)
},
response(fn) {
_this.saveResFn.push(fn)
}
}
}
复制代码
如何调用?
好比在post方法中,请求拦截器应该发送请求之前调用,响应拦截器在返回数据之前调用
cAxios.prototype.post = function (method, url, data) {
// 保存请求的数据
this.data = data
let _this = this
// 在发送请求之前调用请求拦截器的回调函数
if (this.saveReqFn?.length) {
this.saveReqFn.forEach(fn => {
fn(this)
})
}
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open(method, url)
setHeaders(xhr, this.headers)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200 || xhr.status === 304) {
// 创建一个新的对象,将响应的数据保存到新的对象中
let newData = {}
newData.data = JSON.parse(xhr.responseText)
// 在返回数据之前调用响应拦截器的回调函数
if (_this.saveResFn?.length) {
_this.saveResFn.forEach(fn => {
fn(newData)
})
}
resolve(xhr.responseText)
} else {
reject(new Error(xhr.statusText))
}
}
}
xhr.send(JSON.stringify(data))
})
}
复制代码
4.完整代码
function cAxios() {
// 保存请求拦截器中的回调函数
this.saveReqFn = []
// 保存响应拦截器中的回调函数
this.saveResFn = []
// 保存请求的数据
this.data = []
let _this = this
this.interceptors = {
request(fn) {
_this.saveReqFn.push(fn)
},
response(fn) {
_this.saveResFn.push(fn)
}
}
}function setHeaders(xhr, headers) { for (let key in headers) { xhr.setquestHeader(key, headers[key]) }}cAxios.prototype.create = function (obj) {
let axios = new cAxios()
axios.headers = obj.headers;
axios.baseUrl = obj.baseUrl;
return axios
}cAxios.prototype.post = function (method, url, data) { // 生存请求的数据 this.data = data let _this = this // 在发送请求之前调用请求拦截器的回调函数 if (this.saveReqFn?.length) { this.saveReqFn.forEach(fn => { fn(this) }) } return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.open(method, url) setHeaders(xhr, this.headers) xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200 || xhr.status === 304) { // 创建一个新的对象,将请求的数据生存到新的对象中 let newData = {} newData.data = JSON.parse(xhr.responseText) // 在返回数据之前调用响应拦截器的回调函数 if (_this.saveResFn?.length) { _this.saveResFn.forEach(fn => { fn(newData) }) } resolve(xhr.responseText) } else { reject(new Error(xhr.statusText)) } } } xhr.send(JSON.stringify(data)) })}let axios = new cAxios()export { axios}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4