Code前端首页关于Code前端联系我们

一、为啥Vue2项目需要proxy?

terry 2个月前 (06-06) 阅读数 100 #Vue
文章标签 Vue2;代理

做Vue2项目开发时,有没有碰到过“跨域请求被浏览器拦截”的情况?比如调后端接口时,控制台报错“Access to XMLHttpRequest at xxx from origin xxx has been blocked by CORS policy”,这时候很多人会听说用proxy解决,可proxy到底是干啥的?配置起来难不难?实际开发咋用?今天咱就把Vue2里的proxy掰开揉碎讲清楚,从原理到配置再到踩坑,一次性搞懂~

先搞明白“跨域”是咋回事,浏览器有个「同源策略」,只有协议、域名、端口全一样的请求才算“同源”,不同源的请求会被拦截,比如前端开发时,本地启动的服务是 http://localhost:8080,而后端接口域名是 https://api.example.com,协议、域名都不一样,这就触发跨域了。

那开发阶段咋解决跨域?常见方案有三种:

  • 后端开CORS:后端在响应头加 Access-Control-Allow-Origin 等字段,允许前端域名访问,但开发时可能后端还没配,或者想自己控制,不够灵活。
  • JSONP:利用 script 标签不受同源策略限制的特点,但只能发 GET 请求,还得后端配合返回特定格式(比如用回调函数包裹数据),局限性很大。
  • proxy代理:这是前端在开发阶段最常用的方式!原理是借助 webpack-dev-server(Vue2项目默认用webpack打包,开发时启动的本地服务)做“中间人”:前端请求先发给本地devServer,devServer再把请求转发到后端域名,因为浏览器只和本地devServer通信(同源),devServer和后端通信(服务器之间请求没浏览器限制),所以绕开了跨域限制。

proxy在Vue2里咋配置?

Vue2项目的配置文件是 vue.config.js(如果没有就新建),重点看 devServer.proxy 这个配置项,下面一步步拆解配置逻辑,再举个实战例子~

核心配置项解释

配置 proxy 时,主要关注这几个属性:

  • target:要代理到的后端域名(必须带协议,http://https://)。
  • changeOrigin:是否修改请求头里的 origin,设为 true 后,后端会以为请求是从自己的域名发过来的(否则后端可能识别出是前端代理的,导致权限拦截)。
  • pathRewrite:路径重写,前端请求带的前缀(/api),后端接口可能没有这个前缀,所以要把前缀替换掉。

实战配置案例

假设后端接口域名是 https://api.example.com,前端所有以 /api 开头的请求都要代理到这里,配置代码如下:

module.exports = {
  devServer: {
    proxy: {
      '/api': { // 匹配请求路径中以“/api”开头的请求
        target: 'https://api.example.com', // 后端真实域名
        changeOrigin: true, // 开启后,请求头的origin会变成target的域名
        pathRewrite: { '^/api': '' } // 把请求路径里的“/api”替换成空字符串
      }
    }
  }
}

举个请求的例子:前端用 axios 发请求 axios.get('/api/user'),经过代理后,实际发给后端的请求是 https://api.example.com/user(因为 pathRewrite/api 去掉了)。

多代理场景咋配?

如果项目要同时代理多个后端域名(比如用户接口和管理接口),可以这样写:

devServer: {
  proxy: {
    '/user-api': { // 用户模块接口
      target: 'https://user.example.com',
      changeOrigin: true,
      pathRewrite: { '^/user-api': '' }
    },
    '/admin-api': { // 管理模块接口
      target: 'https://admin.example.com',
      changeOrigin: true,
      pathRewrite: { '^/admin-api': '' }
    }
  }
}

前端请求 /user-api/login 会代理到 https://user.example.com/login,请求 /admin-api/list 会代理到 https://admin.example.com/list,灵活区分不同模块的接口~

proxy实际开发咋用?

配置好 proxy 后,前端发请求时要注意和代理规则匹配,还要分清开发环境生产环境的区别。

结合axios发请求

很多项目用 axios 发请求,可以在 main.js 里配置基础路径,让所有请求自动带上代理前缀:

import axios from 'axios'
axios.defaults.baseURL = '/api' // 和proxy的key“/api”对应
// 登录请求示例
axios.post('/login', { username: 'xxx', password: 'xxx' })
  .then(res => {
    console.log(res.data)
  })

这样,请求会先发到本地 devServer(http://localhost:8080/api/login),再由 devServer 转发到后端域名。

开发vs生产环境的区别

proxy 只在开发环境生效(执行 npm run serve 时)!因为生产环境没有 webpack-dev-server,部署项目时要靠后端配置 CORS 或者用 nginx 反向代理,所以开发时用 proxy 绕开跨域,生产时换其他方案,这点一定要注意~

验证代理是否生效

可以打开浏览器的「Network」面板,看请求的 URL:如果请求地址是 http://localhost:8080/api/login,但响应数据来自后端域名,说明代理成功,如果请求地址直接是后端域名,说明代理没生效,得回去检查配置~

proxy和其他跨域方案有啥不同?

前面提了 CORS、JSONP,再加上生产环境用的 nginx,和 proxy 对比看看各自的优劣:

方案 适用场景 优点 缺点
proxy 开发阶段前端自主解决 不依赖后端,支持所有请求方法,配置简单 仅开发环境可用
CORS 生产+开发环境 生产环境通用,一劳永逸 开发阶段需后端配合配置
JSONP 老旧项目兼容 无需额外服务,利用script标签 仅支持GET,需后端配合格式
nginx 生产环境部署 性能好,适合线上反向代理 开发阶段用不上,配置复杂

能看出来,proxy 是开发阶段前端最友好的方案:不用等后端,自己配几行代码就能解决跨域,还支持 POST、PUT 等请求方法,日常开发首选~

proxy配置常见问题咋解决?

配了 proxy 却不生效?接口返回 404?跨域问题还在?别慌,这些坑大多有规律,逐一排查:

代理配置不生效

  • 检查配置文件:确认 vue.config.js 存在,且 devServer.proxy 配置正确,改了配置后要重启devServer(重新执行 npm run serve)。
  • 路径匹配问题:proxy 的 key 是 /api,但请求路径是 /Api(大小写敏感),或者请求路径是 /api2(没匹配到 /api),都会导致代理失效。
  • changeOrigin没开:如果后端验证 origin,没设 changeOrigin: true 会被后端拦截,记得打开。

代理后接口404

  • target地址错误:检查后端域名是否写对(比如少了 https://,或者域名拼写错了),还要确认后端服务是否正常启动。
  • pathRewrite错误:比如前端请求是 /api/v1/login,但 pathRewrite: { '^/api': '' } 会把路径变成 /v1/login,如果后端接口是 /api/v1/login,就会404,这时候要确认后端接口的真实路径,调整 pathRewrite(比如改成 '^/api': '/api',或者后端接口确实没有 /api 前缀)。

跨域问题仍存在

  • 请求没走代理:看浏览器 Network 里的请求 URL,如果是后端域名直接请求,说明代理没匹配到(比如请求路径是 /abc,但 proxy 配的是 /api)。
  • 多个代理规则冲突:webpack-dev-server 的 proxy 是按顺序匹配的,把更具体的规则放前面(/api/v1 要比 /api 先配),避免优先级问题。

Vue2 里的 proxy 是开发阶段解决跨域的“神器”:通过 webpack-dev-server 做中间代理,让前端请求绕开浏览器同源策略,配置时要注意 targetchangeOriginpathRewrite 这几个关键项,结合 axios 发请求时要匹配代理前缀,还要分清开发和生产环境的区别,碰到问题时,从配置文件、路径匹配、后端服务这几个方向排查,基本能解决90%的坑~

现在再回头看开头的跨域报错,是不是觉得 proxy 没那么神秘了?下次开发时碰到跨域,直接配 proxy 开干就完事儿~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

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

热门