Vue encapsula la intercepción de solicitudes (incluido refreshToken) y configura la configuración básica global de vue.config.js (incluidas las variables de entorno de producción y desarrollo)

Tabla de contenido

1. Cree un archivo request.js para solicitar la intercepción y el encapsulado

1. Importación de paquetes

2. Cree una instancia de axios y la configuración relacionada

3. interceptor

2. Configuración básica de vue.config.js (configure devServer.proxy, el objetivo es la dirección de la interfaz)


1. Cree un archivo request.js para solicitar la intercepción y el encapsulado

1. Importación de paquetes

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

2. Cree una instancia de axios y la configuración relacionada

La configuración de baseURL aquí se basa en devServer.proxy en vue.config. Para obtener más información, consulte la configuración básica de vue.config.js a continuación.

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. interceptor

Determine la fecha de vencimiento del token: expires es una fecha de vencimiento del token que nos proporciona el backend después de la solicitud de inicio de sesión o la solicitud de refreshToken. Aquí, el procesamiento del backend de expires es la marca de tiempo cuando se creó el token + la duración del token = expires .

Mi juicio sobre el token aquí es ajustar la interfaz para actualizar el token diez segundos antes de que caduque, y el tiempo se determina de acuerdo con la situación.

Si el token caduca, suspenda la solicitud y guárdela en la matriz, y reemplace el token anterior con el token nuevo después de actualizar el 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);
  }
);

2. Configuración básica de vue.config.js (configure devServer.proxy, el objetivo es la dirección de la interfaz)


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