vite 跨域(长文解析)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

在现代 Web 开发中,跨域问题是一个绕不开的技术挑战。随着前端框架的快速迭代,Vite 凭借其极快的开发构建速度和零配置特性,逐渐成为开发者的新宠。然而,当开发者使用 Vite 构建项目时,常常会遇到与跨域相关的困惑,例如:为什么请求会被浏览器拦截?如何在 Vite 中优雅地解决这一问题?本文将从基础概念到实战案例,深入浅出地解析 vite 跨域 的核心原理和解决方案,帮助开发者快速上手并掌握这一技能。


跨域问题的本质:浏览器的安全机制

在开始讲解 vite 跨域 之前,我们需要先理解跨域(CORS,Cross-Origin Resource Sharing)的定义和原理。

什么是跨域?

跨域指的是在浏览器中,当一个网页中的脚本试图访问不同源(协议、域名、端口三者任意一个不同)的资源时,浏览器会基于同源策略(Same-Origin Policy)拦截该请求。例如,前端页面运行在 http://localhost:3000,而请求的接口地址是 http://api.example.com:8080,此时因为域名和端口不同,浏览器会直接阻止请求。

形象比喻:可以将跨域想象为快递公司之间的协作问题。假设某快递公司只在本市范围内提供服务(同源),但用户要求其将包裹送到另一个城市的仓库(跨域),快递公司会直接拒绝,除非目标仓库所属的快递公司同意合作。

浏览器的保护机制

同源策略是浏览器内置的安全机制,旨在防止恶意网站通过脚本窃取用户隐私或攻击其他网站。例如,如果用户登录了银行网站(https://bank.com),而另一个恶意网站(http://evil.com)试图通过脚本读取银行网站的 cookie,浏览器会拦截这一行为。


Vite 的默认行为与跨域问题

Vite 在开发环境中默认启动了一个本地开发服务器(基于 Vite 的内置开发服务器),该服务器会处理静态资源请求和代理配置。然而,当开发者直接发起对第三方接口的请求时,仍然会遇到跨域问题。

Vite 开发服务器的特点

Vite 的开发服务器有以下特点:

  1. 零配置启动:开发者无需额外配置即可启动服务,默认端口为 3000
  2. HMR(热更新)支持:代码修改后无需刷新页面即可更新。
  3. 代理功能:通过 vite.config.js 配置代理,可解决跨域问题。

为何使用 Vite 仍会遇到跨域?

即使使用 Vite 的开发服务器,若后端接口未配置 CORS 头或未使用代理,浏览器仍会拦截请求。例如,前端页面运行在 http://localhost:3000,请求 http://api.example.com:8080/data 时,浏览器会因跨域问题返回错误。


解决 Vite 跨域问题的 3 种方法

接下来,我们将详细讲解三种解决 vite 跨域 的方法:代理配置、后端设置 CORS 头、使用第三方代理工具。

方法一:通过 Vite 代理配置(推荐)

Vite 提供了内置的代理配置功能,通过修改 vite.config.js 文件,可以将前端请求转发到目标接口,绕过浏览器的跨域限制。

配置步骤

  1. 安装依赖:Vite 默认支持代理功能,无需额外安装。
  2. 修改 vite.config.js:在配置文件中添加 server.proxy 字段。
// vite.config.js
export default defineConfig({
  server: {
    proxy: {
      '/api': {  // 前缀匹配,所有以 /api 开头的请求会被代理
        target: 'http://api.example.com:8080', // 目标接口地址
        changeOrigin: true, // 改写请求头的 host 为 target
        rewrite: (path) => path.replace(/^\/api/, ''), // 去除前缀
      },
    },
  },
});

使用示例

前端代码中发起请求时,使用代理前缀 /api

// src/api/fetchData.js
async function fetchData() {
  const response = await fetch('/api/data'); // 实际请求 http://api.example.com:8080/data
  return response.json();
}

关键点解释

  • changeOrigin:设置为 true 后,请求头中的 Host 字段会被修改为 target 的域名和端口,避免后端因 Host 不匹配而拒绝请求。
  • rewrite:用于去除代理前缀,确保后端接口能正确解析路径。

方法二:后端配置 CORS 头

另一种解决方案是让后端接口主动允许跨域请求。例如,后端可以返回以下响应头:

Access-Control-Allow-Origin: *  // 允许所有来源(生产环境需指定具体域名)
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

优点:无需修改前端代码,适合后端可控的场景。
缺点:若后端无法修改配置(如第三方接口),则此方法不可用。

方法三:使用第三方代理工具

若后端无法配置 CORS,且无法修改 Vite 配置,可以借助第三方工具(如 http-proxy-middleware)或 Nginx 作为反向代理。

示例:使用 http-proxy-middleware

  1. 安装依赖

    npm install http-proxy-middleware --save-dev
    
  2. 创建代理配置文件

    // src/middleware/proxy.js
    import { createProxyMiddleware } from 'http-proxy-middleware';
    
    export default [
      {
        context: ['/api'],
        target: 'http://api.example.com:8080',
        changeOrigin: true,
        pathRewrite: { '^/api': '' },
      },
    ];
    
  3. 修改 vite.config.js

    import proxy from './src/middleware/proxy';
    
    export default defineConfig({
      server: {
        proxy: proxy,
      },
    });
    

实战案例:从问题到解决方案

案例背景

假设我们正在开发一个电商网站,前端使用 Vite,后端接口部署在 http://fake-api.com:3001。当尝试请求商品列表时,浏览器返回以下错误:

Access to fetch at 'http://fake-api.com:3001/products' from origin 'http://localhost:3000' has been blocked by CORS policy.  

解决步骤

  1. 配置 Vite 代理
    vite.config.js 中添加代理配置:

    export default defineConfig({
      server: {
        proxy: {
          '/api': {
            target: 'http://fake-api.com:3001',
            changeOrigin: true,
            rewrite: (path) => path.replace(/^\/api/, ''),
          },
        },
      },
    });
    
  2. 修改前端请求代码
    将请求路径改为代理前缀:

    // src/views/Products.js
    async function getProducts() {
      const response = await fetch('/api/products'); // 请求会被代理到 http://fake-api.com:3001/products
      return response.json();
    }
    
  3. 验证结果
    重启开发服务器后,浏览器的网络请求面板显示请求成功,且响应头中包含 Access-Control-Allow-Origin


常见问题与解决方案

问题 1:代理配置后仍报错

可能原因

  • 目标接口地址错误(如 target 配置不正确)。
  • 路径重写规则未正确移除前缀。

解决方案
检查 target 是否与目标接口地址完全匹配,并确保 rewrite 函数正确。例如:

rewrite: (path) => path.replace(/^\/api/, '')

问题 2:HTTPS 接口的代理问题

若目标接口使用 HTTPS,需在代理配置中添加 secure: falserejectUnauthorized: false

proxy: {
  '/api': {
    target: 'https://secure-api.com',
    secure: false,
    changeOrigin: true,
    ...(process.env.NODE_ENV === 'development' && {
      // 开发环境忽略证书验证
      agent: new https.Agent({ rejectUnauthorized: false }),
    }),
  },
}

总结

通过本文,我们系统地梳理了 vite 跨域 的核心概念、实现原理及解决方案。无论是通过 Vite 内置代理、后端配置 CORS,还是第三方工具,开发者都可以根据项目需求选择最合适的方案。

关键要点回顾

  • 跨域是浏览器的安全机制,需通过代理或后端配置解决。
  • Vite 的代理配置简单高效,是开发环境的最佳实践。
  • 生产环境需确保后端正确设置 CORS 头或使用反向代理。

希望本文能帮助开发者快速解决 vite 跨域 问题,提升开发效率。如果遇到具体问题,欢迎在评论区讨论!

最新发布