VUE3拦截器及axios请求与跨域处理

拦截器代码request-wrapper.ts,首先要自己安装axios与element-plus两个插件:

/*
 * @description: 请求封装
 * * @Author: yp
 * @Date: 2023-02-19 
 * @LastEditors: yp
 * @LastEditTime: 2023-02-19
 */
// 导入axios
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
// 使用element-ui ElMessage做消息提醒  ElLoading加载
import { ElMessage, ElLoading } from "element-plus";


//加载配置
let loadingInstance: any,
    requestNum: number = 0,
    loading: boolean = true;

//加载动画
const addLoading = () => {
    // 防止重复弹出
    requestNum++;
    if (requestNum == 1) {
        loadingInstance = ElLoading.service({ fullscreen: true });
    }
}

// 关闭 加载动画
const cancelLoading = () => {
    requestNum--;
    // 关闭 加载动画
    if (requestNum === 0) loadingInstance?.close();
}

//请求配置
export const createAxios = (
    config?: AxiosRequestConfig,
): AxiosInstance => {
    const instance = axios.create({
        //请求头
        baseURL: window.location.origin,
        // baseURL: '/api',
        //超时配置
        timeout: 60000,
        //跨域携带cookie
        withCredentials: true,
        // 自定义配置覆盖基本配置
        ...config,
    });

    // 添加请求拦截器
    instance.interceptors.request.use(
    
        function (config: any) {
            // console.log("请求拦截器config:", config);
            //加载动画
            if (loading) addLoading();
            console.log(config)

            return config;
        },
        function (error) {
            // 请求错误
            return Promise.reject(error)
        }
    )

    // 添加响应拦截器
    instance.interceptors.response.use(
        
        function (response) {
            debugger
            console.log("响应拦截器response:", response);
            // 关闭加载 动画
            if (loading) cancelLoading();
            if (response.data.code != 200) { 
                ElMessage.error(response.data.msg)
            }
            //返回参数
            return response.data;
        },
        function (error) {
            // 关闭加载 动画
            if (loading) cancelLoading();
            /***** 接收到异常响应的处理开始 *****/
            if (error && error.response) {
                // 1.公共错误处理
                // 2.根据响应码具体处理
                switch (error.response.status) {
                    case 400:
                        error.message = '错误请求'
                        break;
                    case 401:
                        error.message = '未授权,请重新登录'
                        break;
                    case 403:
                        error.message = '拒绝访问'
                        break;
                    case 404:
                        error.message = '请求错误,未找到该资源'
                        break;
                    case 405:
                        error.message = '请求方法未允许'
                        break;
                    case 408:
                        error.message = '请求超时'
                        break;
                    case 500:
                        error.message = '服务器端出错'
                        break;
                    case 501:
                        error.message = '网络未实现'
                        break;
                    case 502:
                        error.message = '网络错误'
                        break;
                    case 503:
                        error.message = '服务不可用'
                        break;
                    case 504:
                        error.message = '网络超时'
                        break;
                    case 505:
                        error.message = 'http版本不支持该请求'
                        break;
                    default:
                        error.message = `连接错误${error.response.status}`
                }
            } else {
                // 超时处理
                if (JSON.stringify(error).includes('timeout')) {
                    error.message = '服务器响应超时,请刷新当前页'
                } else {
                    error.message = '连接服务器失败'
                }
            }
            //提示
            ElMessage.error(error.message)
            /***** 处理结束 *****/
            return Promise.resolve(error.response)
        }
    )

    return instance;
}

创建api.ts文件,封装请求方法,其中包括post,get,postFom, postFile:

/*
 * @description: 请求接口 配置
 * @Author: yp
 * @Date: 2023-02-19 
 * @LastEditors: yp
 * @LastEditTime: 2023-02-19
 */
//导入 Axios 请求
import { createAxios } from './request-wrapper'
import Qs from 'qs'
const request = createAxios();
//其他配置
import operate from '../utils/operate';
export const apiPost = {
    // get 请求
    exportGet : (url: string,params: any): Promise<any> =>
        request.get(url, { params }),
    exportPost : (url: string,data: any) =>
    //请求 token 添加
    // request.post("/export", Object.assign(data, { token: operate.isToken() }));
    request.post(url, data, {
        headers: {
            'content-type': 'application/json;charset=UTF-8',//设置请求头请求格式为json
            'accessToken': operate.isToken() //设置token 其中k名要和后端协调好
        }
    }
        ),
exportPostForm : (url: string, data: any) => {
    //请求 token 添加
    // request.post("/export", Object.assign(data, { token: operate.isToken() }));
    request.post(url, Qs.stringify(data), {
        headers: {
            "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
            'accessToken': operate.isToken() //设置token 其中k名要和后端协调好
        }
    }
    );
    },
exportPostFile : (url: string, data: any) => {
    const forms = new FormData();
    forms.append('file', data)
    request.post(url, forms, {
        headers: {
            'Content-Type': 'multipart/form-data',
            'accessToken': operate.isToken() //设置token 其中k名要和后端协调好
        }
    }
    );
},
}



 
//   postFile: function (url,file,callback) {
//        var forms = new FormData();
//        alert(JSON.stringify(file))
//        forms.append('file',file)
//      axios.post(url,forms,{
//                  headers:{'Content-Type':'multipart/form-data','accessToken': localStorage.getItem("accessToken")}
//           }).then(response => {
//            callback(response);
//           })
//           .catch(error => {
//            console.log("请求失败:",error);
//            reject(error)
//           })
//    },

/*
请求配置与使用

* POST 请求 方式
    export const 名字 = (data: any) =>
        request.post("接口", data, {
            直接为空
            注:只能配置 AxiosRequestConfig 里有的参数名 可不用配置
        });

* GET 请求 方式
    export const 名字 = (params: any): Promise<any> =>
        request.get("接口", { params });

*使用 方法
   *引入
        import {
            名字
        } from "../api/api"
    *生命周期中 请求
        名字({请求参数}).then((res) => {
            console.log(res)
        })
*/

最后就是解决跨域问题,创建operate.ts文件,用于获取token以及判断代码运行环境:

/*
 * @description: 自定义 ts
 * @Author: yp
 * @Date: 2023-02-19 
 * @LastEditors: yp
 * @LastEditTime: 2023-02-19
 */
// vuex 数据
import {store} from '../store/index'
export default {
    //接口地址
    baseUrl: function (): string {
        console.log(process.env.NODE_ENV)
        if (process.env.NODE_ENV == "development" || process.env.NODE_ENV == "test") {
            //开发环境
            return 'http://192.168.194.23:8082/';
        } else {
            //正式环境
            return "production";
        }
    },
    //获取用户token
    isToken: function ():any {
        console.log(store.state.Authorization)
        if (store.state.Authorization != '') {
            return store.state.Authorization
        }
        return false;
    },


}

 创建vite.config.ts,配置跨域代理,前提是使用的是vite创建的项目:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from "path"
import operate from './src/utils/operate'
// https://vitejs.dev/config/
// const url = 'http://192.168.193.108:8082/equipment'
const url = operate.baseUrl()
// const url = 'https://www.wanandroid.com'
console.log(url)
export default defineConfig({
  plugins: [
     vue({
      // template: {
      //   compilerOptions: {
      //     isCustomElement: (tag) => ['my-son'].includes(tag),
      //   }
      // }
    })
   ],
  resolve: {
    // ↓路径别名,主要是这部分
    alias: {
      "@": resolve(__dirname, "./src")
    }
  },
  // 'equipment/tpmSystem/getTree'
  server: { //主要是加上这段代码

      proxy: {
        //所有以 '/equipment'为前缀的接口都转向url
        '/equipment/': {
          target: url,	//实际请求地址
          changeOrigin: equipment,
            //去掉接口中的 '/api'以便和后端接口匹配
          rewrite: (path) => path.replace(/^\//, '')
      },
          '/sale/': {
          target: url,	//实际请求地址
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\//, '')
      },
        '/oauth/': {
				target: url,//设置你调用的接口域名和端口号 别忘了加http
				//  target:'http://daitaowx.mynatapp.cc' ,
				changeOrigin: true,
				rewrite: (path) => path.replace(/^\//, '')
			},
      }
    }
})

  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端你鹏哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值