Vue3 项目里遇到跨域问题该咋解决?
做Vue3项目的时候,不少同学会碰到接口请求被浏览器拦截、控制台报CORS错误的情况,这就是跨域问题在捣乱啦,跨域咋产生的?Vue3里到底该咋解决?接下来咱们一步步把这些事儿掰碎了说。
先搞懂“跨域”到底是啥?
浏览器为了安全,有个同源策略的规则——只有当网页的协议、域名、端口都和请求的接口一致时,才能正常发请求,要是有一个不一样,比如本地Vue项目跑在localhost:5173,后端接口在https://api.xxx.com,协议、域名、端口都对不上,浏览器就会拦截请求,这就是跨域。
Vue3 开发时为啥容易碰到跨域?
开发阶段,前端项目一般用Vite或者Vue CLI启动本地服务(比如Vite默认跑在5173端口),但后端服务可能部署在另一个域名、另一个端口,甚至另一个服务器上,这时候前端发请求,域名/端口和后端对不上,跨域问题就冒出来了。
开发阶段咋解决跨域?(代理是关键!)
开发时不想让浏览器拦请求,最方便的办法是本地代理——让前端请求先发给本地服务,再由本地服务转发给后端,这样浏览器会觉得是“同源请求”,就不拦截了。
Vite 项目配置代理(改vite.config.js)
Vite里配代理很简单,在vite.config.js里加server.proxy:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
// 匹配以 /api 开头的请求
'/api': {
target: 'https://xxx.com', // 后端真实接口地址
changeOrigin: true, // 把请求头里的Origin改成target的地址(骗后端是同源请求)
rewrite: (path) => path.replace(/^\/api/, '') // 把请求路径里的 /api 前缀去掉(后端接口没这个前缀时用)
}
}
}
})
举个例子:前端用axios.get('/api/user')发请求,Vite会把请求转发到https://xxx.com/user,绕开浏览器的跨域拦截。
Vue CLI 项目配置代理(改vue.config.js)
如果用Vue CLI创建的项目,就在vue.config.js里配devServer.proxy:
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://xxx.com', // 后端地址
changeOrigin: true, // 开启跨域
pathRewrite: { '^/api': '' } // 去掉 /api 前缀
}
}
}
}
原理和Vite一样,都是让本地服务帮我们转发请求,骗过浏览器的同源策略。
生产环境咋处理跨域?
开发时的代理只适合本地用,线上部署后,前端和后端已经不在同一个“本地服务”了,这时候得换思路:要么让后端开CORS权限,要么用反向代理。
让后端配置CORS响应头
后端服务主动告诉浏览器:“允许这个前端域名来请求我!” 具体咋配?看后端语言:
-
Node.js(Express框架):
加中间件统一处理响应头:const express = require('express'); const app = express(); // 全局允许跨域(生产环境建议指定具体前端域名,别直接用*) app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', 'https://www.xxx.com'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); // 允许的请求方法 res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 允许的请求头 next(); }); -
Java(Spring Boot):
可以用@CrossOrigin注解(局部接口允许跨域),或者写全局配置类:import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 所有接口 .allowedOrigins("https://www.xxx.com") // 允许的前端域名 .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true); // 允许带Cookie } }
后端配好后,浏览器收到响应头里的Access-Control-Allow-Origin,就会允许前端跨域请求了。
用反向代理(Nginx/Apache)
要是不想改后端代码,还能让服务器当“中间人”,比如用Nginx配置反向代理:
server {
listen 80;
server_name www.xxx.com; # 前端部署的域名
# 处理接口请求的反向代理
location /api {
proxy_pass https://api.xxx.com; # 后端接口的真实域名
add_header Access-Control-Allow-Origin *; # 允许所有域名跨域(生产建议指定)
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE';
add_header Access-Control-Allow-Headers 'Content-Type, Authorization';
}
# 处理前端静态资源(比如打包后的dist文件)
location / {
root /usr/share/nginx/html; # 前端静态文件存放路径
index index.html;
}
}
这样前端请求www.xxx.com/api/user时,Nginx会转发到后端https://api.xxx.com/user,同时给响应头加CORS权限,实现跨域。
跨域解决时的常见坑点
就算知道方法,实操时也可能掉坑里,这些细节得注意:
代理配置后请求404?
检查这两点:
target地址对不对?比如后端接口是不是https://xxx.com,有没有少写路径?rewrite或pathRewrite有没有把前缀处理对?比如后端接口本身就有/api前缀,那前端请求/api/user时,代理就不该去掉/api,否则会变成请求https://xxx.com/user,导致404。
生产环境CORS配置后还是报错?
- 别把
Access-Control-Allow-Origin设为(星号)!如果前端请求带Cookie,是不允许的,得改成具体前端域名。 - 后端有没有处理OPTIONS预检请求?有些复杂请求(比如带自定义头、PUT/DELETE方法),浏览器会先发OPTIONS请求探路,后端得返回200并带上CORS头,否则会报错。
带Cookie的跨域请求咋处理?
前端用axios时,要加withCredentials: true:
axios.get('/api/user', { withCredentials: true });
后端也要配Access-Control-Allow-Credentials: true,同时Access-Control-Allow-Origin不能是,得写具体前端域名。
总结解决思路
跨域问题本质是浏览器的安全限制,解决思路分场景:
- 开发阶段:用Vite或Vue CLI的代理,让本地服务转发请求,绕开浏览器拦截。
- 生产阶段:要么让后端配CORS响应头,要么用Nginx等做反向代理,让前端和后端“看起来同源”。
带Cookie、预检请求这些细节得盯紧,不然容易配了半天还报错,把这些逻辑理清楚,Vue3项目里的跨域问题就再也难不住你啦~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网



发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。