注意http-proxy-middleware要解决跨域问题,想修改origin请求头不要设置changeOrigin=true

复制代码
在使用http-proxy-middleware的时候,有一个配置是"changeOrigin",通过名字来看这个字段是用来控制是否修改origin的,但是实际使用下来,你会发现,当设置为true的时候,header中的origin的值并不会修改,而是修改的host的值。
为什么修改是host呢?那么要修改origin请求头,又应该如何处理呢?下面我就一步一步展开研究一下。
去看一下http-proxy-middleware的源码

不知道怎么去看源码?

我带你一步一步去找找看。

首先工程中安装了http-proxy-middleware,那么在你的node_modules目录下面就会找到http开头的几个目录

根据名字,我们猜测应该在 http-proxy 开头的几个文件中,那么范围就很小了,就可以挨个去找一下。

最后,我们找到,这个的相关源码是在http-proxy包中的common.js中。

c 复制代码
if (options.changeOrigin) {
    outgoing.headers.host =
      required(outgoing.port, options[forward || 'target'].protocol) && !hasPort(outgoing.host)
        ? outgoing.host + ':' + outgoing.port
        : outgoing.host;
  }

可以看到,这里只是修改了header中的host属性,并没有对origin进行任何处理。

思考两个问题
changeOrigin修改的是host,那么这个host的主要作用什么?
如果我们想修改origin,该怎么处理?

回答第一个问题,其实就是弄明白http协议中header中的host的作用。

其实在http-proxy-middleware的GitHub的readme中,有对changeOrigin的注释说明,从这段说明中就可以看出,修改host的作用是为了什么

c 复制代码
options.changeOrigin: for virtual hosted sites

for virtual hosted sites也就是说为了虚拟主机而设置的。

那么虚拟主机是个什么东西呢?

举个例子:

有一个服务器,性能非常好,我想在这个机器上面部署了很多网站,但是这个机器对外的ip只有一个,要实现能访问这个机器上面的不同网站怎么办?

通过ip+端口?是一个办法,但是不太好,我们通常都是通过域名去访问一个网站,而且一般都不指定特定域名,而采用默认的80或者443端口。

那么我如何实现仅仅通过不同的域名就能访问到同一台机器的不同网站呢?那就是靠我们上面说的host来实现的。

当我们通过不同域名访问的时候,虽然通过域名解析都是指向同一台机器,但是这台机器收到请求后,就可以通过请求头中的host来判断本次请求是要访问哪个网站了,这就是host请求头的作用。

通过上面的解释,我们可以知道host请求头和跨域没有关系。

我们回到正题来,一般我们去设置changeOrigin字段,可能往往是想解决跨域的问题。

但是发现,设置了以后,么有生效,估计这才是你能看到这篇博客的原因。O(∩_∩)O哈哈~

那么我们沿着这个问题继续刨根问底。解决跨域,应该怎么处理?应该修改origin请求头。但是通过设置changeOrigin=true,修改的确实host请求头,而不是origin(这个名字起的确实让我们猝不及防,你就不能改成changeHost吗???)

那么我们怎修改origin请求头呢?很简单,去看createProxyMiddleware的函数就行了,到里面找找看,有没有提供给外面一个接口去修改请求值的地方。

看一下createProxyMiddleware函数的定义,我们得知里面是一个Options<TReq, TRes>

继续去看Options的定义,我们可以找有一个on的属性,需要提供一个OnProxyEvent对象

继续看这个对象,我们可以看到有一个proxyReq的属性,猜测这个应该就是提供给外面的接口,用于修改request的请求的地方。

那么我就通过实现proxyReq 方法来进修改request的header了,最后实现案例如下:

c 复制代码
const proxyReq =(proxyReq, req, res, options) =>{
  ///  在这里可以对原始的request 进行修改
  proxyReq.removeHeader('origin');
  console.log('proxyReq getHeaders', proxyReq.getHeaders());
}
app.use(createProxyMiddleware({
      pathFilter:'/api/v1.0',
      target: proxyUrl,
      changeOrigin: true,//控制服务器接收到的请求头中host字段的值,注意不是origin的值!! 修改origin还得用onProxyReq事件
      secure: false,
      on: {
        proxyReq: proxyReq
      },
      logger: console // 添加日志以便调试
    })
  );
总结一下

通过上面一步一步的分析来,让我们学到的不仅仅是这一个知识点,而是要学习一种分析解决问题的方法方式。授之于鱼,不如授之于渔。

相关推荐
shykevin3 小时前
python开发Streamable HTTP MCP应用
开发语言·网络·python·网络协议·http
tmacfrank4 小时前
网络编程中的直接内存与零拷贝
java·linux·网络
数据与人工智能律师6 小时前
虚拟主播肖像权保护,数字时代的法律博弈
大数据·网络·人工智能·算法·区块链
purrrew7 小时前
【Java ee初阶】HTTP(2)
网络·网络协议·http
火星数据-Tina7 小时前
从HTTP轮询到WebSocket:如何让体育API性能提升100倍?
websocket·网络协议·http
hgdlip10 小时前
怎么快速换电脑浏览器的ip:方法与注意事项
网络·网络协议·tcp/ip·电脑
可怜的Tom被玩弄于股掌之中10 小时前
BUUCTF——Nmap
网络·安全·web安全·网络安全
今儿敲了吗11 小时前
计网| 网际控制报文协议(ICMP)
网络·智能路由器
南棱笑笑生12 小时前
20250515测试飞凌的OK3588-C的核心板在Linux R4下适配以太网RTL8211F-CG时跑iperf3的极速
linux·服务器·网络
Think Spatial 空间思维12 小时前
【HTTPS基础概念与原理】TLS握手过程详解
数据库·网络协议·https