本文将简单讲述ajax请求封装,将以axios插件和fetch原生封装做代码演示。请求封装一般需要封装请求头,是否携带token,响应拦截器结构数据等等操作。

axios请求封装:
1、安装axios:yarn add axios(也可以npm i axios,其他工具大同小异)
2、导入axios
import axios from 'axios'
3、配置基地址和超时时间
const baseURL = 'http://localhost:3000'
const ins = axios.create({ //axios常规封装方式
baseURL,
timeout: 4000
})4、配置请求拦截器(用于在请求头携带token)
ins.interceptors.request.use((config) => { //请求拦截器
const token = info.value?.token //读取token
config.headers.Authorization = token ? "bearer " + token : '' //有token就携带token
return config
})5、配置响应拦截器
ins.interceptors.response.use((res) => { //响应拦截器
if (res.status >= 200 && res.status < 300) { //200-300状态是响应成功,处理响应成功逻辑
const totalStr = res.headers['x-total-count'] //将请求头携带的数据赋值给totalStr
if (totalStr) { //判断,有就返回data和total属性的对象
return {
data: res.data,
total: parseInt(totalStr)
}
} else {
return res.data
}
}
throw new Error('未知错误') //throw是vue3中的抛出一个错误(类似promise)
}, (err) => {
window.$message.error(err.message) //响应失败就展示后端返回的失败信息(消息提示前面挂载到windows了的,所以可以使用)
})6、封装 一个请求类型集合函数
function entity(key) { //封装的请求集合,将路由传入进来
return { //返回一个属性是函数的对象(调用对应请求对象,可传入数据)
get(params) {
return ins.get('/' + key, { params })
},
post(data) {
return ins.post('/' + key, data)
},
put(id, data) {
return ins.put('/' + key + '/' + id, data)
},
patch(id, data) { //打补丁,哪里修改就改哪里
return ins.patch('/' + key + '/' + id, data)
},
delete(id) {
return ins.delete('/' + key + '/' + id)
},
deleteAll(ids) {
const req = (id) => {
return ins.delete('/' + key + '/' + id)
}
return Promise.allSettled(ids.map(req))
}
}
}7、封装导出一个对象,对象属性名就是对应的请求方法,属性值就是调用上方的请求集合函数,并在此处写入请求路径参数
export const apis = { //封装的api请求对象
users: entity('users'),
schools: entity('schools'),
dynamicCategories: entity('dynamicCategories'),
dynamicContents: entity('dynamicContents'),
carousels: entity('carousels'),
studentSources: entity('studentSources'),
studentSourceStates: entity('studentSourceStates'),
studentSourceLevel: entity('studentSourceLevel'),
studentsBefore: entity('studentsBefore'),
}8、封装一个上传文件的方法
// 上传文件
export function upload(file) { //手动封装的上传文件,参数为file文件
const formData = new FormData() //文件需要formData格式,这里new一个FormData实例
formData.append('file', file) //将传来的file丢入formData里
return fetch(baseURL + '/file', { //用fetch发请求
method: "POST",
body: formData
}).then(res => res.text()).then(res => baseURL + res)
//上一行中,.text()是让其返回文本格式数据
} 其他组件或者js代码需要用到请求时,可以直接import 导入对应的方法即可使用
fetch请求的理解:
流程:请求->一帧一帧地发给后端->后端进行处理->一帧一帧地返回给前端。每一帧,都包含头信息和状态码
xhr.onProgress每一帧触发,得到数据量
fetch res.body是一个可读流,流的读取也可以记录进度
详细描述:
1、原生请求,fetch xhr一样的功能,只是fetch是Promise风格
2、fetch第一个参数是url,第二个参数是配置项
3、fetch可以配置:method请求方法,headers请求头,body请求体
4、fetch请求如果发送get/dalete,参数放在-----路径参数(path/params),查询参数(?key=value&key=value)
5、fetch接收的数据有两段,第一段描述信息,还没有返回结束,只是第一帧的http,能拿到status状态码,htaders返回头,决定使用何种方式处理返回体:res.json解析成对象,res.text解析成文本,res.blob解析成文件
6、fetch第二段then,返回体解析后的结果
fetch请求基本使用:
fetch(url, {
method, // 请求方法
headers, // 请求头
body, // 二进制或字符串
}).then(res=>{
// 在返回第一帧的时候执行
// res.headers 返回头
// res.status 返回状态码
return res.json() // text/blob
}).then(res=>{
console.log(res) // 结果
})fetch请求封装:
1、闭包原理,内层函数访问外层函数变量的引用
2、内层函数可以当做请求拦截器,可以做一些请求之前的处理,例如携带token
3、then可以看做响应拦截器,可以做对数据进行结构处理,以及判断并确定返回数据的类型
// 路径参数和查询参数在 path 传进来
function request(method, path, data){
// 组装基地址
let url = baseUrl + path
// 可以看成 axios 请求拦截器
return fetch(url, {
method,
body: data?JSON.stringify(data):undefined,
headers:{
"Authorization":"Bearer " + localStorage.getItem('token')
}
}).then(res=>{
// 可以看成 axios 的响应拦截器
if(res.status >=200 && res.status < 300){
return res.json()
}else{
throw new Error(res.status)
}
}).catch(err=>{
// 错误处理
})
}
request('GET', `/users?name=${name}`)请求封装个人随笔结尾:
本站文章均原创,可以转载,禁止克隆。关于请求封装有更好的理解则可以评论在下方,投稿可以直接联系站长或者发入投稿邮箱!