vue中如何解决跨域 - 完整解决方案与实战教程

在前后端分离的开发架构中,Vue 项目通常运行在本地开发服务器(如 http://localhost:8080),而后端 API 服务可能部署在另一台服务器或另一个端口(如 http://192.168.1.100:3000)。当你在 Vue 组件中调用后端接口时,浏览器控制台会抛出 “Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy” 的红色错误,接口请求完全失败。这个跨域问题是 Vue 开发者最高频的排坑场景之一,尤其在本地联调和测试环境切换时极易卡住进度。本文将从现象、根因到三种实战方案,帮你彻底解决 Vue 中的跨域难题。

【问题现象】

你在 Vue 组件中这样写请求:

// 组件内发起请求
import axios from 'axios';

axios.get('http://192.168.1.100:3000/api/user/list')
  .then(res => console.log(res))
  .catch(err => console.error(err));

浏览器控制台报错如下:

Access to XMLHttpRequest at 'http://192.168.1.100:3000/api/user/list' 
from origin 'http://localhost:8080' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

【原因分析】

跨域问题的本质是浏览器的同源策略(Same-Origin Policy)。同源是指协议、域名、端口三者完全相同。只要有一项不同,浏览器就会拦截响应。注意:请求实际上已经发送到后端,后端也返回了数据,但浏览器拒绝将响应交给前端 JS 代码

常见触发场景包括:

很多开发者误以为“后端加了 Access-Control-Allow-Origin: * 就万事大吉”,但在携带 Cookie 或需要精确控制时,通配符会失效。因此,在 Vue 开发阶段,最推荐、最干净的做法是通过开发服务器代理转发请求,让浏览器以为请求同源。

【解决方案(附完整代码)】

以下三种方案按推荐程度排序,覆盖 Vue CLI 和 Vite 两种主流构建工具。

方案一:Vue CLI 项目配置 devServer.proxy(最常用)

在项目根目录的 vue.config.js 中配置代理。若文件不存在,手动创建。

// vue.config.js
module.exports = {
  devServer: {
    // 配置代理规则
    proxy: {
      // 匹配所有以 /api 开头的请求路径
      '/api': {
        // 目标后端地址,注意不要加 /api
        target: 'http://192.168.1.100:3000',
        // 允许改变 origin,解决部分后端校验 Host 的问题
        changeOrigin: true,
        // 是否启用 https 校验,false 表示忽略证书问题
        secure: false,
        // 路径重写:去掉请求路径中的 /api 前缀
        // 例如 /api/user/list -> /user/list
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
};

配置完成后,必须重启开发服务器npm run serve)。然后在组件中这样请求:

// 请求路径改为相对路径 /api,由 devServer 代理转发
axios.get('/api/user/list')
  .then(res => console.log(res))
  .catch(err => console.error(err));

此时浏览器认为请求的是 http://localhost:8080/api/user/list,同源,无跨域。devServer 在内部将请求转发到 http://192.168.1.100:3000/user/list

方案二:Vite 项目配置 server.proxy(Vue 3 + Vite 推荐)

vite.config.jsvite.config.ts 中配置:

// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()],
  server: {
    proxy: {
      '/api': {
        target: 'http://192.168.1.100:3000',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
});

同样重启 npm run dev,请求方式与方案一一致。

方案三:后端配置 CORS 响应头(生产环境必备)

开发代理只解决本地问题,生产环境必须由后端设置正确的 CORS 头。以 Node.js Express 为例:

// 后端 Express 中间件
app.use((req, res, next) => {
  // 允许的前端源,生产环境不要用 *
  res.setHeader('Access-Control-Allow-Origin', 'https://your-frontend.com');
  // 允许的请求方法
  res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
  // 允许的请求头
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization');
  // 允许携带 Cookie
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  // 预检请求直接返回 204
  if (req.method === 'OPTIONS') {
    return res.sendStatus(204);
  }
  next();
});

若使用 Nginx 反向代理,可在配置中添加:

location /api/ {
    proxy_pass http://192.168.1.100:3000/;
    add_header Access-Control-Allow-Origin 'https://your-frontend.com';
    add_header Access-Control-Allow-Methods 'GET,POST,PUT,DELETE,OPTIONS';
    add_header Access-Control-Allow-Headers 'Content-Type,Authorization';
    if ($request_method = 'OPTIONS') {
        return 204;
    }
}

排查步骤清单

  1. 确认报错是 CORS 而非 404/500,打开 Network 面板查看请求头。
  2. 检查 vue.config.jsvite.config.js 是否配置了 proxy,且路径匹配规则正确。
  3. 修改配置文件后是否重启了开发服务器。
  4. 请求 URL 是否使用了代理前缀(如 /api),而不是直接写后端完整地址。
  5. 若携带 Cookie,后端 Access-Control-Allow-Origin 不能为 *,且需设置 credentials: true
  6. 生产环境检查 Nginx 或后端框架的 CORS 配置是否生效。

掌握以上三种方案,Vue 跨域问题将不再是你开发路上的拦路虎。开发用代理,生产配 CORS,双管齐下最稳妥。