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 的开发服务器有以下特点:
- 零配置启动:开发者无需额外配置即可启动服务,默认端口为
3000
。 - HMR(热更新)支持:代码修改后无需刷新页面即可更新。
- 代理功能:通过
vite.config.js
配置代理,可解决跨域问题。
为何使用 Vite 仍会遇到跨域?
即使使用 Vite 的开发服务器,若后端接口未配置 CORS 头或未使用代理,浏览器仍会拦截请求。例如,前端页面运行在 http://localhost:3000
,请求 http://api.example.com:8080/data
时,浏览器会因跨域问题返回错误。
解决 Vite 跨域问题的 3 种方法
接下来,我们将详细讲解三种解决 vite 跨域 的方法:代理配置、后端设置 CORS 头、使用第三方代理工具。
方法一:通过 Vite 代理配置(推荐)
Vite 提供了内置的代理配置功能,通过修改 vite.config.js
文件,可以将前端请求转发到目标接口,绕过浏览器的跨域限制。
配置步骤
- 安装依赖:Vite 默认支持代理功能,无需额外安装。
- 修改
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
-
安装依赖:
npm install http-proxy-middleware --save-dev
-
创建代理配置文件:
// src/middleware/proxy.js import { createProxyMiddleware } from 'http-proxy-middleware'; export default [ { context: ['/api'], target: 'http://api.example.com:8080', changeOrigin: true, pathRewrite: { '^/api': '' }, }, ];
-
修改
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.
解决步骤
-
配置 Vite 代理:
在vite.config.js
中添加代理配置:export default defineConfig({ server: { proxy: { '/api': { target: 'http://fake-api.com:3001', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ''), }, }, }, });
-
修改前端请求代码:
将请求路径改为代理前缀:// src/views/Products.js async function getProducts() { const response = await fetch('/api/products'); // 请求会被代理到 http://fake-api.com:3001/products return response.json(); }
-
验证结果:
重启开发服务器后,浏览器的网络请求面板显示请求成功,且响应头中包含Access-Control-Allow-Origin
。
常见问题与解决方案
问题 1:代理配置后仍报错
可能原因:
- 目标接口地址错误(如
target
配置不正确)。 - 路径重写规则未正确移除前缀。
解决方案:
检查 target
是否与目标接口地址完全匹配,并确保 rewrite
函数正确。例如:
rewrite: (path) => path.replace(/^\/api/, '')
问题 2:HTTPS 接口的代理问题
若目标接口使用 HTTPS,需在代理配置中添加 secure: false
和 rejectUnauthorized: 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 跨域 问题,提升开发效率。如果遇到具体问题,欢迎在评论区讨论!