likes
comments
collection
share

axios请求封装&拦截器

作者站长头像
站长
· 阅读数 7

axios设置超时时间

axios.default.timeout=15000

post请求头的设置

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';

axios的请求拦截

在请求的header中携带token
axios.interceptors.request.use((config) => {
  const token = UserModule.token;
  let needToken = token && token.length > 0;
  if (needToken) {
    config.headers.Authorization = token;
  }
  return config;
});

axios响应拦截

判断返回状态是不是200,统一处理一些错误
  async (response) => {
    const { config } = response;
    // 没有权限或者token失效
    if (Number(response.data.code) === 401) {
      UserModule.LoginOut({ message: I18N.common.loginExpierd });
      return Promise.reject("error");
    }
      const { data, config, headers } = response;
      // 判断是否是200
    if (isSimpleResponse(data) && Number(data?.code) !== 200) {
      const error = new Error(data?.msg ?? "Unknown Error");
      error.name = data.code.toString();
      Message({
        message: error.message,
        // message: "操作失败",
        type: "warning",
        duration: 3 * 1000,
      });

      return Promise.reject(error);
    }
    return response;
  },
    async (error) => {
      let { data } = error.response;
      const config = error.config as AxiosRequestConfig;
      // blob错误类型是blob 需要转换
      if (error.response.config.responseType === "blob") {
        data = await resolveBlobRsp(data);
      }
      if (typeof data === "string") {
        error.name = error.response.status.toString();
        error.message = error.response.statusText;
      } else {
        error.name = data.status.toString();
        error.message =
          data.message ?? `${error.name} ${data.error}` ?? "Unknown Error";
      }
      Message({
        message: error.message,
        type: "warning",
        duration: 3 * 1000,
      });
      UserModule.ResetUser();
      return Promise.reject(error);
    }
);
封装get方法
export function get(url,params){
	return new Promise((resolve,reject)=>{
    	axios.get(url,{
        	params: params 
        }).then(res => {
            resolve(res.data);
        }).catch(err =>{
            reject(err.data)        
    	})    
    })
}
封装post方法
import QS from 'qs'
export function post(url,params){
	return new Promise((resolve,reject)=>{
    	axios.post(url, QS.stringify(params)).then(res => {
            resolve(res.data);
        }).catch(err =>{
            reject(err.data)        
    	})    
    })
}
补充1: 使用QS对post提交的参数序列化QS.stringify(params)
  • 序列化和反序列化
序列化指对象------->JSONString,反序列化指JSONString------>JSONObject或对象。
JSONString: 'age':'10'
补充:post提交数据的方式 (post提交的数据必须放在消息主体entity-body中,但并没有规定必须是使用什么编码方式)
  • content-type的类型 默认属性: application/x-www-form-urlencode
是按照key,value拼接的方式(key value都做了url转码处理) key1=val1&key2=val2
  • multipart/form-data
 一般用于上传文件 FormData
  • application/json
消息主体是序列化后的json字符串{"title":"test","sub":[1,2,3]}

需要从返回的返回头里面获取文件名

axios接口异步请求处理时间得钩子responseHook
  • 1.声明钩子函数
declare module "axios" {
  interface AxiosRequestConfig {
    /** 接口报错时是否显示警告,默认为开启  */
    warn?: boolean;
    /** 响应返回钩子  */
    responseHook?: (res: AxiosResponse) => void;
  }
}
  • 2.在axios拦截器里调用钩子函数
axios.interceptors.response.use(
sync (response) => {
	const { config } = response;
     // 处理事件钩子
    if (config?.responseHook) {
      config.responseHook(response);
    }
 }
)
  • 3.调用接口时使用钩子函数
{
  responseType: "blob",
  // 响应返回钩子 获取rsp数据
  responseHook: (rsp) => {
    exportTitle = getExportTitle(rsp, "***.xlsx");
  },
}
// 获取导出的文件名
export function getExportTitle(rsp: AxiosResponse<any>, defaultTitle: string) {
  let exportTitle =
    rsp.headers["content-disposition"].split("=")?.[1] ?? defaultTitle;
  exportTitle = decodeURI(exportTitle); //解码
  return exportTitle;
}