• 【Vue3+TS】Axios拦截器封装及跨域 [cors] 解决方案


    简述

    我的项目采用 Vue3+TypeScript+Vite+Element Plus 的组合,这个组合也是Vue版本退出3.x后官方推荐版本,给出的理由是Vue3的底层实现用的是TypeScript。
    我这里用的包管理器是pnpm

    Axios官方介绍:
    Axios 是一个基于 promise 网络请求库,作用于node.js浏览器 中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests

    Axios 包的安装
    pnpm install axios --save

    封装过程

    文件路径

    在项目的src文件夹下创建http文件夹
    http文件夹包含 Interceptor.tsAPI.ts 两个文件
    路径

    拦截器封装 —— Interceptor.ts

    import axios from 'axios';
    import { ElMessage } from 'element-plus';
    
    // 创建axios实例
    const $http = axios.create({
      // 请求的域名,基本地址,proxy 代理时会将“/api”以及前置字符串会被替换为真正域名
      baseURL: '/api',
      // 跨域请求时发送Cookie
      // withCredentials: true, // 视情况而定
      // 超时时间
      timeout: 5000,
      headers: {
        'content-type': 'application/json; charset=utf-8'
      }
    });
    
    // 请求拦截器
    $http.interceptors.request.use((config) => {
      config.headers = config.headers || {};
      if (localStorage.getItem("token")) {
        config.headers.token = localStorage.getItem("token") || "";
      }
      return config;
    });
    
    // 响应拦截器
    $http.interceptors.response.use((response) => {
      return response;
    }, (error) => {
      ResponseProcessing(error);
    });
    
    /**
     * 响应处理
     * @param error 
     * @returns 
     */
    const ResponseProcessing = (error: { response: { state: any; data: any; }; }) => {
      if (error.response) {
        switch (error.response.state) {
          case 401:
            ElMessage.warning("资源没有访问权限!");
            break;
          case 404:
            ElMessage.warning("接口不存在,请检查接口地址是否正确!");
            break;
          case 500:
            ElMessage.warning("内部服务器错误,请联系系统管理员!");
            break;
          default:
            return Promise.reject(error.response.data); // 返回接口返回的错误信息
        }
      } else {
        ElMessage.error("遇到跨域错误,请设置代理或者修改后端允许跨域访问!");
      }
    };
    
    export default $http;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    进行最基础的封装,我个人认为易于调用的封装便是好的封装,适度即可以免造成过度封装。

    API请求管理

    import $http from './Interceptor';
    
    export default {
      WeatherForecast() {
        return $http({ url: "/WeatherForecast", method: "get" });
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    前端跨域的解决方案

    在vite.config.ts文件中添加 proxy 配置

    import { defineConfig } from 'vite';
    import vue from '@vitejs/plugin-vue';
    
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [
        vue(),
      ],
      server: {
        proxy: {
          "/api": { // “/api” 以及前置字符串会被替换为真正域名
            target: "https://localhost:7166/", // 请求域名
            secure: false, // 请求是否为https
            changeOrigin: true, // 是否跨域
            rewrite: (path) => path.replace(/^\/api/, "")
          }
        }
      }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    proxy 配置中:坑爹的地方 secure 配置请求是否为https,这里指的是发起的请求,不是目标接口的请求是否为 https

    后端跨域的解决方案

    这里后端用的是 【C#】.net6 web api 默认项目模板为例。这么用的主要原因是,C#是我使用最熟练的编程语言。
    .net6 中解决跨域也是十分的便捷,我这里配置允许所有,下面一起来看看吧

    • 在Program.cs文件中进行配置

    需要注意两点:
    1、添加cors配置
    2、注册中间件

    // 添加配置
    builder.Services.AddCors(option =>
    {
       option.AddPolicy("cors", builder =>
       {
           builder.AllowAnyMethod().SetIsOriginAllowed(_ => >true).AllowAnyHeader().AllowCredentials();
       });
    });
    
    // 注册中间件 AddPolicyName 要与前面一致
    app.UseCors("cors");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 注意:如果需要用到UseMvc()中间件那么 UseCors() 一定要在 UseMvc() 之前,我这里没有用到所以注释掉

    完整配置及插入点

    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    
    builder.Services.AddControllers();
    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();
    
    // cors 跨域配置
    builder.Services.AddCors(option =>
    {
        option.AddPolicy("cors", builder =>
        {
            builder.AllowAnyMethod().SetIsOriginAllowed(_ => true).AllowAnyHeader().AllowCredentials();
        });
    });
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI();
    }
    
    // 注册中间件 AddPolicyName 要与前面一致
    app.UseCors("cors");
    // app.UseMvc();
    app.UseHttpsRedirection();
    
    app.UseAuthorization();
    
    app.MapControllers();
    
    app.Run();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    效果

    在这里插入图片描述

    在这里插入图片描述

    结语

    跨域问题弄明白了还是很容易解决的,一般来说,只需要在一端解决跨域即可,并且一般建议使用后端跨域解决方案。
    后面会单独出一篇后端跨域的多种解决方案和各种方案的适用范围以及如何选择最佳方案。

  • 相关阅读:
    u盘被格式化了文件还可以恢复吗?
    Python--用户输入与While循环
    网页显示不全(运行时网页pc端显示完全,手机端显示不全)
    Vue.js vs React:哪一个更适合你的项目?
    JSP核心技术的进阶(指令、标签、对象域)+JSTL+EL
    实践一年之久,vivo 如何基于 APISIX 进行业务基础架构的演进
    时间复杂度
    Golang 中 map 探究
    MySQL 某个字段存储不了内容
    Java实现发送Get、Post请求仅需两步
  • 原文地址:https://blog.csdn.net/qq_43562262/article/details/127936228