美文网首页
使用axios封装fetch(qs+包含token配置+cont

使用axios封装fetch(qs+包含token配置+cont

作者: 浅浅_2d5a | 来源:发表于2021-08-13 11:09 被阅读0次

较为复杂的Fetch.js

import axios from 'axios';
import Qs from 'qs';
import { Toast } from 'vant';
import { cookie  } from './common';
import {Message} from "element-ui";
import {refreshToken} from "../view/management/permission/refreshPermission";
import router from '../view/management/router';
const CODE_SUCCESS = 100000;

// 创建axios实例
const service = axios.create({
  baseURL: process.env.BASE_API, // api的base_url
  transformRequest: [function (data) {
    return Qs.stringify(data);
  }],
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
  },
  timeout: 50000

});
// request拦截器
service.interceptors.request.use((config) => {
  //domain(权限接口) 和 merchantCode(商户接口)
  if(config.domain){
    config.headers.domain = config.domain;
  }
  if(config.merchantCode === 'merchantChoose'){
    config.headers.merchantCode = cookie.getCookie('merchantCode');
  }
  // if(config.merchantCode === 8001){
  //   config.headers.merchantCode = config.merchantCode;
  // }
  //只要不是登录的接口,都要设置权限
  if(config.url.indexOf('auth/login')==-1){
    config.headers.authorization = 'Bearer '+cookie.getCookie('interfaceToken')
  }
  // 当token涉及到临期,并且有interfaceToken 请求refresh_token 
  if( !cookie.getCookie('tokenValid') && cookie.getCookie('interfaceToken') && !cookie.getCookie('hasRresh')){
    //刷新token的接口,加个cookie,控制只进入一次
    cookie.setCookie('hasRresh',true);
    refreshToken().then((data)=>{
      config.headers.authorization = 'Bearer '+cookie.getCookie('interfaceToken')
      //避免二次编译
      if(config.headers["Content-Type"] === 'application/json'){
        config.data = JSON.parse(config.data)
      }
      return axios.request(config);
    })
  }
  return config;
}, (error) => {
  // 可以在这里统一处理请求错误
  Promise.reject(error);
});

service.interceptors.response.use((response) => {
  let res = response.data;
  if (res && res.code !== CODE_SUCCESS) {
    //时间长不操作,token失效,跳转登录
    if(res.code === 100141){
      router.push('/login')
    }    
    // 可以在这里统一处理响应错误
    if(res.code !== 400201){
      Message({
        type: 'error',
        message: response.data.msg == null?'请求异常':response.data.msg
      });
      console.log('liuli',res.msg)
      throw 'bliliil'
      // return Promise.reject(response.data);
    }
  }
  return response.data;
}, (error) => {
  // 可以在这里统一处理响应错误
  return Promise.reject(error);
});

service.subPath = process.env.SUB_PATH;

export default service;

思考总结:
1、返回拦截器中处理逻辑

service.interceptors.response.use((response) => {
  let res = response.data;
  if (res && res.code !== 100000) {
      return Promise.reject(response.data);
  }
  return response.data;
}, (error) => {
  // 可以在这里统一处理响应错误
  return Promise.reject(error);
});

当返回的code不等于100000时,但status为200,说明接口调通了,返回数据,但是可能是电话号码重复、密码出错等原因,需要给用户提示。
如果进入error,应该就是接口没调通
上述2种都返回了 Promise.reject对象。如果进入这里,调用接口地方必须用catch接收。否则报错


image.png

即便是.catch(()=>{})也需要
如果不想每次调用接口都加上.catch(),可以改写成抛出错误
throw response.data
throw error
会在控制台抛出错误。
如果此时调用接口的地方用了catch接收。throw就打印不出来了,错误被吞了,因此如果工程写了n多代码后,改Fetch配置一定要加小心

继续思考,为什么下面要抛出Promise.reject对象

  if (res && res.code !== 100000) {
      return Promise.reject(response.data);
  }

如果直接返回数据,会进入调用接口方法的.then方法。Promise.reject的情况会进入.catch方法。是为了不同code进行区分处理逻辑 error中的return Promise.reject(error);同理

2、Content-Type为www-form格式,如果是json格式如何请求
在接口配置项目的地方增加

     headers: {
        'Content-Type': 'application/json'
      },
      transformRequest: [function (data) {
        data = JSON.stringify(data)
        return data
      }],

3、为什么用qs转码


image.png

qs 会把参数用& 拼接

相关文章

网友评论

      本文标题:使用axios封装fetch(qs+包含token配置+cont

      本文链接:https://www.haomeiwen.com/subject/qalogktx.html