本文将简单讲述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}`)
请求封装个人随笔结尾:
本站文章均原创,可以转载,禁止克隆。关于请求封装有更好的理解则可以评论在下方,投稿可以直接联系站长或者发入投稿邮箱!