欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解axios中封装使用、拦截特定请求、判断所有请求加载完毕)

程序员文章站 2022-04-30 21:33:32
•基于 promise 的 http 请求客户端,可同时在浏览器和 node.js 中使用 •vue2.0之后,就不再对 vue-resource...

•基于 promise 的 http 请求客户端,可同时在浏览器和 node.js 中使用
•vue2.0之后,就不再对 vue-resource 更新,而是推荐使用 axios,本项目也是使用 axios
•功能特性
•在浏览器中发送 xmlhttprequests 请求
•在 node.js 中发送 http请求
•支持 promise api
•拦截请求和响应
•转换请求和响应数据
•取消请求
•自动转换 json 数据
•客户端支持保护安全免受 csrf/xsrf(跨站请求伪造) 攻击

封装使用

建议拆分三个文件

•src
 -> service
 ---->axios.js (axios 配置,拦截器、统一 url)
---->index.js (接口方法,里面调用 api 方法,供页面级调用)
---->api
 ------->index.js(api 方法,里面调用后端提供的接口,供接口方法调用)

axios.js 基本配置

'use strict';
import axios from 'axios';

// 自动识别接口使用开发环境地址(开发环境地址做了 proxytable 代理,故设置为空)或线上地址
axios.defaults.baseurl = process.env.node_env === 'production' ? process.env.api_root : '';
// 开发环境直接打包测试
// axios.defaults.baseurl = '';

axios.interceptors.request.use(config => {
 return config;
}, error => {
 console.log(error);
 return promise.reject(error);
});

axios.interceptors.response.use(res => {
 const apires = res.data;
 return apires;
}, async error => {
 console.dir(error);
 return promise.reject(error);
});

export default axios;

api/index.js 调用后端提供的接口
import ax from '@/service/axios';
import qs from 'qs';

export default {
 fetchblog (reqdata) {
  return ax.get('/krryblog/blog/getblog', {params: reqdata});
 },
 addblog (reqdata) {
  return ax.post('/krryblog/blog/addblog', qs.stringify(reqdata));
 },
 updateblog (reqdata) {
  return ax.post('/krryblog/blog/updateblog', qs.stringify(reqdata));
 },
 deleteblogcover (id, reqdata) {
  return ax.post(`/krryblog/blog/deleteblogcover/${id}`, qs.stringify(reqdata));
 },
};

index.js 接口方法(调用 api)

import api from './api';

export async function getblog(reqdata) {
 let res = await api.fetchblog(reqdata);
 return res;
},
export async function addblog (reqdata) {
 let res = await api.addblog(reqdata);
 return res;
},
export async function updateblog (reqdata) {
 let res = await api.updateblog(reqdata);
 return res;
},
export async function deleteblogcover (id, reqdata) {
 let res = await api.deleteblogcover(id, reqdata);
 return res;
},

页面调用

接下来就可以愉快地在页面调用了

import { getblog } from '@/service'
export default {
 data() {
  return {
   tabledata: [],
   pageindex: 1,
   pagesize: 9
  }
 },
 created() {
  this.getlist();
 },
 methods: {
  async getlist() {
   let { result } = await getblog({
    pageindex: this.pageindex,
    pagesize: this.pagesize
   });
  this.tabledata = result.data;
 },
}

axios 执行多个并发请求

async getlist() {
 let resarr = []
 for (let val of this.arrid) {
  // push 请求
  resarr.push(querypropertyvalue({ id: val }))
 }
 this.tabledata = []
 promise.all(resarr).then(res => {
  for (let val of res) {
   let vals = val.result.propertyvalues
   // 每个请求的结果 push 到 tabledata
   vals.foreach(item => this.tabledata.push(item))
  }
 })
},

或者直接在 axios 写 promise all

// 根据 id 获取某一条商品数据
let getdetail = (id)=>{
 return axios.get(`/detail?bid=${id}`);
}

// 检测登录的用户是否将此商品加入购物车
let detectcar = (shopid,userid)=>{
 return axios.get(`/detectcar?shopid=${shopid}&userid=${userid}`);
}

// 获取一条商品数据、并且检测是否加入购物车
let getdeall = (shopid,userid)=>{
 axios.all([
  getdetail(shopid),
  detectcar(shopid,userid)
 ]).then(axios.spread((resdetail, rescar)=>{
  // 两个请求现已完成
  // 打印两个请求的响应值 
  console.log(resdetail);
  console.log(rescar);
 }));
}

•实例的方法

axios#request(config)
axios#get(url [,config])
axios#delete(url [,config])
axios#head(url [,config])
axios#post(url [,data [,config]])
axios#put(url [,data [,config]])
axios#patch(url [,data [,config]])

•请求配置:只有url是必需的,如果未指定方法,请求将默认为get

axios 拦截特定请求

业务上经常出现这个问题,需要拦截某些特定请求,在该特定请求,页面采取或不采取什么变化

研究 axios 的 request 统一拦截方法:axios.interceptors.request.use(function (config) {})

参数 config 如下:

可以发现 config.url 就是请求的接口的地址,那么 “/” 最后的 getclassify 就是该请求的方法,就可以通过取出该字符串来判断某些特定请求,从而做出怎样的变化

axios.interceptors.request.use(config => {
 // 判断请求是否是 getclassify,如果是 getclassify,不加载 loadingbar
 let url = config.url;
 if (url.split('/').pop() === 'getclassify') {
  flag = false;
 } else {
  iview.loadingbar.start();
  flag = true;
 }
 return config;
}, error => {
 console.log(error);
 return promise.reject(error);
});

如何判断所有请求加载完毕

let reqnum = 0
axios.interceptors.request.use(function (config) {
 // 在请求发出之前进行一些操作,每次发出请求就 reqnum++
 reqnum++
 _bus.$emit('showloading')
 return config
}

axios.interceptors.response.use(response => {
 // 接受请求后 reqnum--,判断请求所有请求是否完成
 reqnum--
 if (reqnum <= 0) {
  _bus.$emit('closeloading')
 } else {
  _bus.$emit('showloading')
 }
})

axios 的 post 请求 相关问题

•如果遇到 post 请求跨域问题,在 webpack 配置文件可以设置 proxytable 处理跨域问题
•传送门:
•post 请求携带参数,需要做一次序列化:qs.stringify(reqdata)

savenormalads (reqdata) {
 return ax.post('/index.php?krry', qs.stringify(reqdata));
},

总结

以上所述是小编给大家介绍的详解axios中封装使用、拦截特定请求、判断所有请求加载完毕),希望对大家有所帮助