vue封装请求拦截(含refreshToken),并配置vue.config.js全局基本配置(含生产和开发的环境变量)

目录

一、创建一个request.js文件,请求拦截封装

1.包引入

2.创建axios实例,相关配置

3.拦截器

二、vue.config.js基本配置(配置devServer.proxy,target为接口地址)


一、创建一个request.js文件,请求拦截封装

1.包引入

import axios from "axios";
import { Notification, Message } from "element-ui";
import errorCode from "@/utils/errorCode";
import store from "@/store/index";

2.创建axios实例,相关配置

这里的baseURL配置根据在vue.config中的devServer.proxy而来,具体请看后面vue.config.js基本配置

axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
// 对应国际化资源文件后缀
axios.defaults.headers["Content-Language"] = "zh_CN";
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.NODE_ENV === "production" ? "/api" : "/dev-api",
  // 超时
  timeout: 30000,
});
//刷新token调用
let tokenHttp = axios.create({
  baseURL: process.env.NODE_ENV === "production" ? "/api" : "/dev-api",
  // 超时
  timeout: 30000,
});

3.拦截器

判断token期限:expires是登录请求或refreshToken请求后,后端反给我们的一个token期限,这里expires后端的处理是,token创建时的时间戳 + token持续时间 = expires

我这里对token的判断是,在token过期前十秒就去调刷新token的接口,时间据情况自定

如果token过期就将请求挂起并存放到数组中,在token刷新过后再将新的token替换旧的token

let refreshing = false;
// 被挂起的请求数组
let subscribesArr = [];

/* push所有请求到数组中 */
function subscribeTokenRefresh(cb) {
  subscribesArr.push(cb);
}

function onRrefreshed(token) {
  subscribesArr.map(cb => cb(token))
}

//判断token期限
//expires是登录请求或refreshToken请求后,后端反给我们的一个token期限
//这里expires后端的处理是,token创建时的时间戳+token持续时间=expires
const tokenExpired = (expires) => {
  let now = new Date().getTime();
  //milliseconds如果大于0说明未过期 
  let milliseconds = expires - now;
  return milliseconds;
};

// request拦截器
service.interceptors.request.use(
  (config) => {
    let nowToken = localStorage.getItem("token");
    //登陆时,会将token以及expires一同存储在localStorage
    let expires = localStorage.getItem("expires");
    //判断token存在,同时tokenExpired(expires) < 10000
    //这样处理是为了在token过期前十秒就去调刷新token的接口,时间据情况自定
    if (nowToken && tokenExpired(expires) < 10000) {
      // 是否在刷新
      if (!refreshing) {
        refreshing = true;
        let refresh = {}
        refresh.refreshToken = localStorage.getItem("refreshToken")
        // 刷新token,定义一个get的refreshToken的接口,传的参数据情况自定
        tokenHttp
        .get("/accessToken/refresh", { params: refresh })
        .then((res) => {
          refreshing = false;
          let param = {
            token: res.data.accessToken,
            refreshToken: res.data.refreshToken,
            expires: res.data.accessTokentime,
          };
            store.commit("login/login", param)
              let newToken = localStorage.getItem('token')
              //请求的token替换为新token
              onRrefreshed(newToken);
              subscribesArr = []
          })
          .catch(() => { });
          //post接口仅供参考
          //tokenHttp.post('/accessToken/refresh', qs.stringify(param))
      }
      const retry = new Promise((resolve, reject) => {
        /* (token) => {...}这个函数就是回调函数*/
        subscribeTokenRefresh((token) => {
          config.headers.Authorization = token
          resolve(config);
        });
      });
      return retry;
    }

    return config;
  },
  (error) => {
    Promise.reject(error);
  }
);

二、vue.config.js基本配置(配置devServer.proxy,target为接口地址)


module.exports = {
    /**
     * 部署生产环境和开发环境下的URL。
     * 默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上
     * 例如 https://www.chinatelecom.cn。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。
     * 例如,如果你的应用被部署在 https://www.chinatelecom.cn/admin/,则设置 baseUrl 为 /admin/。
     */
    publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
    /**
     * 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)
     */
    outputDir: "dist",
    /**
     * 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
     */
    assetsDir: "static",
    /**
     * 是否开启eslint保存检测,有效值:ture | false | 'error'
     */
    lintOnSave: process.env.NODE_ENV === "development",
    /**
     * 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
     */
    productionSourceMap: false,
    /**
     * webpack-dev-server 相关配置
     */
    devServer: {
        /**
         * 配置proxy
         */
        proxy: {
            /**
            * 配置开发接口地址
            */
            ['/dev-api']: {
                target: "http://xxx.xxx.xxx.xxx:8082",
                changeOrigin: true,
                pathRewrite: {
                    ['^/dev-api']: "/",
                },
            },
            /**
            * 配置生产接口地址
            */
            ['/api']: {
                target: "http://xxx.xxx.xxx.xxx:8082",
                changeOrigin: true,
                pathRewrite: {
                    ['^/api']: "/",
                },
            },
        },
    },
};

猜你喜欢

转载自blog.csdn.net/weixin_43721856/article/details/128248939