如果让你来给萌新讲解前端proxy代理,你会怎么讲?

前言

今天看到群里有人在聊前端的proxy代理

A: vue.config.js 中proxy中的 /api 不是代理了请求的后端的地址嘛,他是不是同时也代表这后端接口名中有/api才正确

B: 不对

B: vue.config.js 中proxy中的 /api 只是开开发环境使用,后端不需要做任何更改

B: api 是你本地起的node服务去请求后端,拿到结果给自己同域的的前端项目,这一切的根本原因是浏览器有跨域。服务端没有跨域

B: 你请求的 api 这个服务是你自己的代理服务,这个代理服务然后请求后端服务

B: 前端 proxy 代理 是开发环境,部署上线 需要前端部署 使用 ngxin 反响代理 把 api 代理出去

emm…看完也给我整懵了,B同学看起来是了解proxy,但是我觉得他给A同学讲解的时候有点答非所问~然后自己回想了下,虽然这东西用过了解过,但是如果让我讲解又不知道从何说起,于是决定做个笔记记录下。

使用场景

一般来说使用proxy配置项是为了解决本地开发产生的跨域问题,就比如前端发送一个请求 axios.get("/userInfo") ,浏览器中 http://localhost:8080/userInfo 去访问 https://www.leoleo.com/userInfo 这时候就会产生跨域。

实现原理

为什么通过配置proxy能解决跨域?

我们知道跨域其实是 浏览器的同源策略 导致的,http://localhost:8080/ 和 https://www.leoleo.com/ 显然是非同源的,即使 请求能访问到后端,但是浏览器也无法接收到返回的数据。

proxy原理.png

图中1、2代表没有经过代理的请求与响应,请求虽然到达了服务器,但是服务器返回的数据却会被浏览器拦截。

图中3、4代表经过代理转发后的请求与响应,代理是在本地开启的,所以域名与本地的一致,浏览器发送请求给代理 -> 代理去请求服务器 -> 服务器响应资源返回给代理 -> 代理把资源返回给浏览器 -> 浏览器拿到资源

Q: 代理和服务器域名不一致为什么可以接收服务器资源
A: 跨域是浏览器的限制,服务器之间没有跨域限制

基本配置

通过 proxy 配置项解决跨域问题

devServer: {
    ...
    proxy: {
      '/api': { // 标识字段:匹配访问路径中含有 '/api' 的路径
        target: 'https://www.leoleo.com/', // 配置转发目标地址
        pathRewrite: { // 路径重写配置
          '^/api': ''
        },
        changeOrigin: true, // 控制服务器接收到的请求头中host字段的值
        logLevel: 'debug', // 能打印出代理后的路径
      },
      '/api2': {
          ...
      }
    }
    ...
  }

标识字段

'/api' '/api2' 表示请求地址中需要包含了该字段就会对请求进行代理转发

target

目标地址,需要转发的目标地址

pathRewrite

重写请求路径,'^/api': '' 的意思就是把’/api’ 替换成空

logLevel

能在本地打印出代理后的路径,方便调试

changeOrigin

控制服务器接收到的请求头中host字段的值

假设,如果你的前端服务器是 http://localhost:8080 后端是 https://www.leoleo.com/

那么后端通过 request.getHeader(“Host”) 获取依旧是 http://localhost:8080

如果你设置了 changeOrigin: true,那么后端通过 request.getHeader(“Host”) 获取才是 https://www.leoleo.com/


结合上面的例子,如果想使用这段配置,那么需要在请求中加/api axios.get("/api/userInfo")

经过target的处理,请求路径已经变成了 https://www.leoleo.com/api/userInfo ,再经过pathRewrite的处理,请求路径已经变成了 https://www.leoleo.com/userInfo ,这时候就能正常访问服务器的地址了。

注意事项

一般项目中,前端都会用axios封装请求接口,还会有 .env[mode] 环境配置文件,比如

const service = axios.create({
  ...
  baseURL: process.env.VUE_APP_BASE_API,
  ...
})

这时候就要注意了,如果你的 baseURL 已经配置了域名VUE_APP_BASE_API = 'https://www.leoleo.com/' 那么就算命中了代理配置,也不会走代理配置的!

可以改成 VUE_APP_BASE_API = '/api',这样发送请求的时候也只需要正常请求就可以了 axios.get("/userInfo")

总结

对了,最后回答A的问题,回答是:后端接口不一定需要有/api。如果有,那么pathRewrite就不用配置了,如果没有,那就用pathRewrite去掉/api。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值