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

释放双眼,带上耳机,听听看~!

博客地址:https://ainyi.com/71

  • 基于 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 如下:

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

可以发现 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 处理跨域问题
  • 传送门:https://ainyi.com/27
  • post 请求携带参数,需要做一次序列化:qs.stringify(reqData)
saveNormalAds (reqData) {
  return Ax.post(\'/index.php?krry\', qs.stringify(reqData));
},

博客地址:https://ainyi.com/71

给TA打赏
共{{data.count}}人
人已打赏
随笔日记

大数据技术 - MapReduce 作业的运行机制

2020-11-9 4:16:55

随笔日记

最大子数组的线性时间的算法

2020-11-9 4:16:57

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索