zoukankan      html  css  js  c++  java
  • 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 如下:

    可以发现 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

  • 相关阅读:
    XSS漏洞攻击
    String 是值类型还是引用类型
    客户端验证不能代表服务器端验证
    PowerDesigner参照(Reference)笔记
    LazyAllocate(缓分配)与PreAllocate(预分配)
    我在delphi7下调用微软的Web Services的心得.(可以返回数据集)
    C Dungeon Master
    TimeQuest笔记
    XPStyle Button
    对XML文件的CRUD(添加,读取,搜索,修改,删除)的例子
  • 原文地址:https://www.cnblogs.com/ainyi/p/10676431.html
Copyright © 2011-2022 走看看