项目中使用axios请求拦截

1 请求拦截器介绍

拦截器的作用:用于我们在网络请求的时候发起请求或者响应请求时对操作进行响应的处理。
比如: 发起请求时候可以添加加载动画、token认证强制登陆等;
响应时候进行数据处理

1.1 基本的请求拦截器

axios.interceptors.request.use(config=>{
    console.log("进入请求拦截器")
    return config;//放行请求 *
    //config包含data、headers、request、status、statusText
},err=>{
    console.log("请求失败")
})

1.2 基本的响应拦截器

axios.interceptors.response.use(config=>{
    console.log("响应拦截器")
      //进行拦截操作
    return config;//放行
},err=>{
    console.log("响应失败")
})

项目中的模板

2 vue+vant(轻提示)

其他知识(定义开发环境以及生产环境的地址):
在根目录下定义.env.production文件来存放生产环境地址

# 配置生产地址,就是你将来发布上线的地址 
VUE_APP_URL="http://xxx.xxx.xx.xx:3000"

在根目录下定义.env.development文件来存放生产环境地址

VUE_APP_URL="xxxxxxxxx"

src下创建api/index.js配置拦截

import axios from "axios";
import Vue from "vue";
import { Dialog } from 'vant';
//配置的地址文件
import '../../.env.development'
// vant提供的轻提示组件
import { Toast } from "vant";
Vue.use(Toast);
import store from '@/store/index'

//可以选择使用直接定义的方式,也可以选择导入地址文件的方式(建议真实项目中用导入地址文件的方式)
// let env = "prod";//prod生产环境,dev开发环境
// let baseURL = '';
// if (env === 'dev') {
//   baseURL = 'http://xxx.xxx.xx.xx:3000';
// } else {
//   baseURL = 'http://xxx.xxx.xx.xx:3000';
// }

//导入地址文件的方式
console.log("开发环境",process.env.NODE_ENV);//开发环境,开发状态下是development
console.log("当前开发环境基础地址",VUE_APP_URL)
const service = axios.create({
 // 配置基本路径
 baseURL:VUE_APP_URL,
 timeout: 50000, // 请求超时时间(因为需要调试后台,所以设置得比较大)
});

// request 对请求进行拦截
service.interceptors.request.use(
 (config) => {
   if (config.method === "get") {
     if (config.params) {
       //对于get请求
       if (!config.params.noLoading) {
         // 开启loading
         Toast.loading({
           message: "加载中...",
           forbidClick: true,
           loadingType: "spinner",
         });
       } else {
         delete config.params.noLoading;
       }
     }
   }
   // 请求头添加token
   //前提是使用了vuex配置了store
   config.headers["user-token"] = store.state.token;
   return config;
 },
 (error) => {
   Promise.reject(error);
 }
);

// response 响应拦截器
service.interceptors.response.use(
 (response) => {
   // 清除loading
   Toast.clear();
   const res = response.data;
   if (res.code == 666) {
     return res;
   } else if (res.code == 603) {
     Dialog.confirm({
       title: '温馨提示',
       message: '您还未登录,是否去登录',
     })
       .then(() => {
         // on confirm
       })
       .catch(() => {
         // on cancel
       });
   } else {
     // 成功连接到后台, 但是没有返回正确的数据
     Toast.fail(res.msg);
   }
 },
 (error) => {
   Toast.clear();
   // 跟后台连接失败
   Toast.fail("网络异常,请稍后再试");
 }
);

export default service;

3 vue + elementUi

import axios from "axios";
import {
  ElLoading,
  ElMessage
} from 'element-plus'
let isDev = process.env.NODE_ENV === "development";
// isDev = false;
let baseURL;
if (isDev) {
  baseURL = "xxx.xxx.xxx.xx:3000";
} else {
  baseURL = "xxx.xxx.xxx.xx:3000";
}

const service = axios.create({
  baseURL,
  timeout: 30000, // 请求超时时间(因为需要调试后台,所以设置得比较大)
});

let loadObj;
// request拦截器
service.interceptors.request.use(
  (config) => {
    if (!loadObj) {
      loadObj = ElLoading.service({
        lock: true,
        text: 'Loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
    }
    return config;
  },
  (error) => {
    setTimeout(() => {
      loadObj.close();
    }, 300);
    return Promise.reject(error);
  }
);

// response 拦截器
service.interceptors.response.use(
  (response) => {
    setTimeout(() => {
      loadObj.close();
    }, 300);
    const res = response.data;
    if (res.code == 666) {
      return res;
    } else {
      ElMessage(res.msg);
      return Promise.reject(res.msg);
    }
  },
  (error) => {
    setTimeout(() => {
      loadObj.close();
    }, 300);
    ElMessage(error.message);
    return Promise.reject(error.message);
  }
); 
export default service;

4 react + antdMobile ui

import axios from "axios";
import { Toast, Dialog } from 'antd-mobile'
import React from 'react';

let isProd = process.env.NODE_ENV === "production";
let baseURL;
if (isProd) {
    baseURL = "xxx.xxx.xxx.xx:3000";
} else {
    baseURL = "xxx.xxx.xxx.xx:3000";
}
const service = axios.create({
    baseURL,
    timeout: 10 * 60 * 1000,
});

//4. 请求拦截
service.interceptors.request.use(
    (config) => {
        // config.headers["Content-Type"] = 'application/json;charset=utf-8'
        Toast.show({
            icon: 'loading',
            content: '加载中…',
        })

        if (localStorage.getItem('token')) {
            config.headers["user-token"] = localStorage.getItem('token')
        } else {
            config.headers["user-token"] = ''
        }
        // do something
        return config;
    },
    (err) => {
        return Promise.reject(err);
    }
);

service.interceptors.response.use(
    (res) => {
        Toast.clear();
        if (res.data.code === 603) {
            Dialog.confirm({
                content: '您还未登录,是否前去登录',
                onConfirm: () => {
                    Toast.show({ content: '点击了确认', position: 'bottom' })
                    location.href = 'http://localhost:3000/login'
                },
                onCancel: () => {
                    Toast.show({ content: '取消', position: 'bottom' })
                }
            })

        }

        if (res.data.code !== 666) {
            return Promise.reject(res.data.msg);
        }
        return res;
    },
    (err) => {
        Toast.show({
            icon: 'fail',
            content: '加载失败',
        })

        return Promise.reject(err);
    }
);

export default service;

5 ts+react 项目request进行验证

import axios from "axios";
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
type Result= {
  code: number|string;
  msg: string;
  currPage?:number|string;
  pageSize?:number|string; 
  total?:number;
  result: any;
};
class Request {
  // axios 实例
  instance: AxiosInstance;
  // 基础配置,url和超时时间
  baseConfig: AxiosRequestConfig = { baseURL: "http://xxx.xxx.xx.xx:3000", timeout: 60000 };

  constructor(config: AxiosRequestConfig) {
    // 使用axios.create创建axios实例
    this.instance = axios.create(Object.assign(this.baseConfig, config));

    // 请求拦截器
    this.instance.interceptors.request.use(
      (config: AxiosRequestConfig) => {
        // 一般会请求拦截里面加token
        // const token = localStorage.getItem("token");
        config.headers = { 'user-token': "token值" };
        return config;
      },
      (err: any) => {
        return Promise.reject(err);
      }
    );

    // 响应拦截器
    this.instance.interceptors.response.use(
      (res) => {
        // 直接返回res,当然你也可以只返回res.data
        return res.data;
      },
      (err: any) => {
        // 这里用来处理http常见错误,进行全局提示
        let message = "";
        switch (err.response.status) {
          case 400:
            message = "请求错误(400)";
            break;
          case 401:
            message = "未授权,请重新登录(401)";
            // 这里可以做清空storage并跳转到登录页的操作
            break;
          case 403:
            message = "拒绝访问(403)";
            break;
          case 404:
            message = "请求出错(404)";
            break;
          case 408:
            message = "请求超时(408)";
            break;
          case 500:
            message = "服务器错误(500)";
            break;
          case 501:
            message = "服务未实现(501)";
            break;
          case 502:
            message = "网络错误(502)";
            break;
          case 503:
            message = "服务不可用(503)";
            break;
          case 504:
            message = "网络超时(504)";
            break;
          case 505:
            message = "HTTP版本不受支持(505)";
            break;
          default:
            message = `连接出错(${err.response.status})!`;
        }
        // 这里错误消息可以使用全局弹框展示出来
        // 比如element plus 可以使用 ElMessage
        // ElMessage({
        //   showClose: true,
        //   message: `${message},请检查网络或联系管理员!`,
        //   type: "error",
        // });
        alert('请检查网络或联系管理员');
        // 这里是AxiosError类型,所以一般我们只reject我们需要的响应即可
        return Promise.reject(err.response);
      }
    );
  }

  // 定义请求方法
  public request(config: AxiosRequestConfig): Promise<AxiosResponse> {
    return this.instance.request(config);
  }

  public get<T = any>(
    url: string,
    config?: AxiosRequestConfig
  ): Promise<Result> {
    return this.instance.get(url, config);
  }
  public post<T = any>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig
  ): Promise<Result> {
    return this.instance.post(url, data, config);
  }
  public put<T = any>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig
  ): Promise<Result> {
    return this.instance.put(url, data, config);
  }

  public delete<T = any>(
    url: string,
    config?: AxiosRequestConfig
  ): Promise<Result> {
    return this.instance.delete(url, config);
  }
}
export default Request;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容