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

embedded/2024/12/3 0:42:19/
http://www.w3.org/2000/svg" style="display: none;">
在使用http-proxy-middleware的时候,有一个配置是“changeOrigin”,通过名字来看这个字段是用来控制是否修改origin的,但是实际使用下来,你会发现,当设置为true的时候,header中的origin的值并不会修改,而是修改的host的值。
为什么修改是host呢?那么要修改origin请求头,又应该如何处理呢?下面我就一步一步展开研究一下。
httpproxymiddleware_3">去看一下http-proxy-middleware的源码

不知道怎么去看源码?

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

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

https://i-blog.csdnimg.cn/direct/c135f732b8ca444da738fb1ceeea29ca.png" alt="在这里插入图片描述" />
根据名字,我们猜测应该在 http-proxy 开头的几个文件中,那么范围就很小了,就可以挨个去找一下。
最后,我们找到,这个的相关源码是在http-proxy包中的common.js中。

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

https://i-blog.csdnimg.cn/direct/4ed37127073548ab9a2b37df42b26422.png" alt="在这里插入图片描述" />

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

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

回答第一个问题,其实就是弄明白http协议中header中的host的作用。
其实在http-proxy-middleware的GitHub的readme中,有对changeOrigin的注释说明,从这段说明中就可以看出,修改host的作用是为了什么

options.changeOrigin: for virtual hosted sites

https://i-blog.csdnimg.cn/direct/8acc72accdab48de8d30e79afdc11571.png" alt="在这里插入图片描述" />
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>
https://i-blog.csdnimg.cn/direct/e7793e3fe9cd4f3e8b3eb461449818c0.png" alt="在这里插入图片描述" />
继续去看Options的定义,我们可以找有一个on的属性,需要提供一个OnProxyEvent对象
https://i-blog.csdnimg.cn/direct/ac14d3742d474916a7061fad711874fe.png" alt="在这里插入图片描述" />

继续看这个对象,我们可以看到有一个proxyReq的属性,猜测这个应该就是提供给外面的接口,用于修改request的请求的地方。
https://i-blog.csdnimg.cn/direct/99dde11b8ce94afab19c79f289505dd4.png" alt="在这里插入图片描述" />
那么我就通过实现proxyReq 方法来进修改request的header了,最后实现案例如下:

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 // 添加日志以便调试}));
总结一下

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


http://www.ppmy.cn/embedded/142454.html

相关文章

详解Qt PDF 之 QPdfDocument与 QPdfView 打开与显示pdf

文章目录 使用Qt PDF&#xff1a;QPdfDocument与QPdfView加载与显示PDF文档引言1. QPdfDocument类1.1 QPdfDocument的构造和加载文档1.2 QPdfDocument的主要功能1.3 错误处理和状态管理 2. QPdfView类2.1 QPdfView的构造和文档设置2.2 QPdfView的视图模式2.3 缩放功能2.4 控件的…

008静态路由-特定主机路由

按照如上配置&#xff0c;用192.168.0.1 电脑ping 192.168.1.1 发现能够ping通 用192.168.0.1 电脑ping 192.168.2.1 发现不能ping通 这是因为192.168.0.1 和 192.168.1.1 使用的是同一个路由器R1。 192.168.0.1 和 192.168.2.1 通信需要先经过R1&#xff0c;再经过R2 &#xf…

A02、Java 设计模式优化

1、单例模式 1.1、什么是单例模式 它的核心在于&#xff0c;单例模式可以保证一个类仅创建一个实例&#xff0c;并提供一个访问它的全局访问点。该模式有三个基本要点&#xff1a;一是这个类只能有一个实例&#xff1b;二是它必须自行创建这个实例&#xff1b;三是它必须自行向…

UNDO LOG日志

目录 undo log的作用 undo log的生成与管理 undo log与事务操作 undo log的配置与优化 undo log结构 整体结构 回滚段&#xff08;Rollback Segment&#xff09; undo log段&#xff08;Undo Log Segment&#xff09; undo log页&#xff08;Undo Log Page&#xff09…

Opencv+ROS实现摄像头读取处理画面信息

一、工具 ubuntu18.04 ROSopencv2 编译器&#xff1a;Visual Studio Code 二、原理 图像信息 ROS数据形式&#xff1a;sensor_msgs::Image OpenCV数据形式&#xff1a;cv:Mat 通过cv_bridge()函数进行ROS向opencv转换 cv_bridge是在ROS图像消息和OpenCV图像之间进行转…

使用Hugo和GitHub Pages创建静态网站个人博客

不需要服务器&#xff0c;不需要域名&#xff0c;不需要数据库&#xff0c;可以选择模版&#xff0c;内容为Markdown格式。 Hugo&#xff1a;https://gohugo.io 文档&#xff1a;https://gohugo.io/getting-started/quick-start/ 中文文档&#xff1a;https://www.gohugo.or…

软件工程头歌实训作业:Junit实训入门篇

第1关&#xff1a;第一个Junit测试程序 任务描述 请学员写一个名为testSub()的测试函数&#xff0c;来测试给定的减法函数是否正确。 相关知识 Junit编写原则 1、简化测试的编写&#xff0c;这种简化包括测试框架的学习和实际测试单元的编写。 2、测试单元保持持久性。 3、利用…

20241128解决Ubuntu20.04安装libesd0-dev异常的问题

20241128解决Ubuntu20.04安装libesd0-dev异常的问题 2024/11/28 16:36 缘起&#xff1a;中科创达的高通CM6125开发板的Android10的编译环境需要。 安装异常&#xff1a;rootrootrootroot-X99-Turbo:~$ rootrootrootroot-X99-Turbo:~$ sudo apt-get install libesd0-dev Readi…