今天有人问我关于webpack中proxy相关的问题,于是我想着把proxy好好总结一下,分享给更多的人。
首先声明一下:proxy只用于开发阶段,说白了就是用于本地开发调试。
在开发阶段中,由于浏览器同源策略的原因,当本地访问后端就会出现跨域请求的问题,所以在webpack中配置一个开发服务器webpack-dev-server(后面简称devServer服务器),在devServer服务器中配置proxy,相当于浏览器发出请求时,会先到本地服务器devServer,然后devServer服务器做一个代理转发到对应的后端服务器上。注意:跨域是浏览器的安全策略,服务器之间是不存在跨域的。
我们先看一下简单的代理配置代码。
// ./webpack.config.js
module.exports = {
// 开发服务器配置
devServer: {
port: 8080,
proxy: {
'/ws_payment': {
target: 'http://api.pay.com'
}
}
// ...
}
}
在项目中的应用,下面的请求会请求到 http://api.pay.com/ws_payment/h5/group/verify上
submit () {
this.$http
.post({
// /ws_payment的使用,
url: ‘/ws_payment/h5/group/verify’,
data: this.getSendData(),
})
.then((res) => {
if (res.code === '1') {
location.href = res.data.payUrl;
} else {
this.$message.error(res.msg);
}
})
.catch((reason) => {
this.$message.error(reason);
});
},
那有人就会有疑问了,代码上线之后呢,这样的请求怎么处理? 处理的方式有很多中,我们项目中的处理方式是配置nginx代理(其实原理和本文讲的proxy代理是一样的)。
常用的属性有四个
关于更多的配置信息请查看:webpack官网
// webpack.config.js
devServer: {
proxy: { // 配置代理(只在本地开发有效,上线无效)
"/ws_payment": { // 这是请求接口中要替换的标识
target: "http://api.pay.com", // 被替换的目标地址,即把 /api 替换成这个
pathRewrite: {"^/api" : ""}, // 如果不希望传递/api,则需要重写路径,这个时候请求路径中就没有/api了
secure: false, // 若代理的地址是https协议,需要配置这个属性
changeOrigin: true, // 加了这个属性,那后端收到的请求头中的host是目标地址 target
}
}
}
默认情况下,代理时会保留主机头(host)的来源,可以将 changeOrigin 设置为 true 以覆盖此行为。
关于host,请看我另外一篇文章:http请求头中的origin、referer、host
重点说一下changeOrigin 设置为 true的情况
changeOrigin 设置为 false时
假设你的前端服务器是 http://localhost:3000,后端是 http://localhost:8082。
那么后端通过 request.getHeader(“Host”) 获取依旧是 http://localhost:3000。
changeOrigin 设置为 true时
如果你设置了 changeOrigin: true,那么后端通过 request.getHeader(“Host”) 获取才是 http://localhost:8082。代理服务器此时会根据请求的 target 地址修改 Host。
注意
但是我在本地通过F12打开浏览器的request Header 的 Host,发现无论怎么修改 changeOrigin,它均为前端服务器地址。
如图:
会发现Host的域名端口号和前端资源地址Referer的域名端口号一致。(关于Host和Referer的概念请看我这篇博客:http请求头中的origin、referer、host)。
是不是changeOrigin: true 设置无效?
其实不然。而且,设置已经生效了,只是浏览器不会直观地显示给你。
(接着http://localhost:3000和http://localhost:8082的这个例子说)
你需要通过后端进行 request.getHeader(“Host”) 打印,你就能发现区别了。
当不设置 changeOrigin 的时候,后端输出 http://localhost:3000
当设置 changeOrigin: true 的时候,后端输出 http://localhost:8082
是因为,浏览器只是将第一层请求显示给你(因为第一层请求是请求的本地服务器,域名、端口号和前端页面的域名、端口号都是一致的),第一层请求也就是发给代理服务器的请求,而修改 Host 的工作是代理服务器做的,浏览器当然不会显示 Host 已经被修改的状态!
proxy工作原理实质上是利用http-proxy-middleware 这个http代理中间件,实现请求转发给其他服务器
举个例子:
在开发阶段,本地地址为http://localhost:3000,该浏览器发送一个前缀带有/api标识的请求到服务端获取数据,但响应这个请求的服务器只是将请求转发到另一台服务器中
const express = require('express');
const proxy = require('http-proxy-middleware');
const app = express();
app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true}));
app.listen(3000);
// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar
参考:
https://blog.csdn.net/qq_39291919/article/details/108807111
https://blog.csdn.net/qq_40409143/article/details/116517080