抽丝剥茧:详述一次DevServer Proxy配置无效问题的细致排查过程
事情的起因是这样的,在一个已上线的项目中,其中一个包含登录和获取菜单的接口因响应时间较长,后端让我尝试未经服务转发的另一域名下的新接口,旧接口允许跨域请求,但新接口不允许本地访问(只允许发布测试/生产的域名访问)。
问题
那么问题来了,本地环境该如何成功访问到新的接口并验证业务功能是否生效呢?

尝试过程
我首先就想到了直接在 webpack 项目中配置 devServer,并且修改接口地址(为了安全隐私,隐去公司实际域名,使用 xxxxx 来替代。)
devServer: {
proxy: {
'/': {
target: 'https://xxxxx.cn',
pathRewrite: {
'/proxyApi': '',
},
changeOrigin: true,
},
},
}
但返回的接口提示【登录态无效】,这下起码不跨域了!本来以为已经代理成功,只需要找到后端看看报错即可!
但后端反馈这个报错是因为请求头没有携带指定参数,他也查不到该请求的详细信息。这时候我又开始有疑问了,明明查看请求头是有的呀。!
疑问
在 chrome 浏览器上看到的请求地址并不是后端提供的真实接口请求地址,而是加了我代理的字段。在响应体上我也没有找到 location 等字段反馈到真实的请求接口。
此时的我怀疑,代理是真的生效了吗,我请求的接口是真实的后端接口吗?开始验证 devServer 的 proxy 是否执行。在 proxy 处配置请求前后输出的函数,结果发现 onProxyReq 和 onProxyRes 都没有执行。
proxy: {
'/proxyApi': {
target: 'https://xxxxx.cn',
pathRewrite: {
'/proxyApi': '',
},
changeOrigin: true,
onProxyReq(proxyReq, req, res) {
console.log('>>>请求', req);
},
onProxyRes(proxyRes, req, res) {
// 响应的钩子函数
console.log('>>>响应', res);
},
},
},
所以此时猜测是不是整个 devServer 都没有生效,但如何证明它没有生效呢?
证实
目前代理后端域名不受我们控制,我无从知晓它是否发送到后端服务器上,所以我打算自己用 nodejs 开启一个服务,开启服务的方式很简单,使用核心模块 https 几行代码搞定。
const http = require("http");
const server = http.createServer((req, res) => {
console.log(">>req", req.url, req.rawHeaders );
res.end("hello");
});
server.listen("3002", () => {
console.log("3002端口启动了");
});
通过 node 启动服务后,首先验证是否可拦截请求,直接通过浏览器窗口 输入 localhost:3002

哎~ 服务启动了,页面也得到的响应,服务器能获取到刚刚 get 请求的数据

此时将项目中 proxy 的配置改为 3002 端口的服务,再次执行业务逻辑代码发送请求,发现此时3002端口启动的服务控制台空空如也!也就是说,它根本没有拦截到该请求。
proxy: {
'/proxyApi': {
target: 'http://localhost:3002',
},
猜想是否因为项目里的接口请求工具导致无法拦截,于是直接在页面上使用 fetch 发送请求,此时发现 3002 端口的服务仍然没有接收到请求。
fetch('https://xxxxx.cn/proxyApi/yyyyy/operateTargetNew')
本来以为是不是 proxy 字符匹配的问题,因为 /proxyApi 标识出现在整个url 中间,试图修改为正则表达式 "**/proxyApi/*",也是无效的
proxy: {
'**/proxyApi/*': {
},
再次尝试
这时候我意识到一个问题,带有域名的接口访问好像不行,那我直接去掉域名呢?
此时直接使用 fetch 请求不包含域名的接口地址
fetch('/proxyApi/yyyyy/operateTargetNew')
这个时候,终于看到了问题即将解决的曙光!调用接口成功获取到了 3002 端口返回的响应

也能在本地的 3002 端口服务上获取到请求的详细信息。

拨开云雾
查询资料发现果然是接口地址的原因。Webpack DevServer的proxy配置主要用于开发环境中,针对的是由本地DevServer发出的API请求。
当你在前端代码中发送请求时,通常会使用相对路径(如/api/xxx/yyy),这样它们就会被发送到当前页面所在的主机和端口,也就是Webpack DevServer。
这时,DevServer的proxy设置可以将请求转发到配置的后端服务器。
// webpack.config.js
module.exports = {
// ...
devServer: {
proxy: {
'/api': {
target: 'http://your-backend-server.com',
changeOrigin: true,
},
},
},
};
现在,如果你发送一个请求到/api/xxx/yyy,DevServer会将它代理到http://your-backend-server.com/api/xxx/yyy。
然而,如果你在前端代码中直接使用了完整的URL(即包含域名https://www.xxxx.com/api/xxx/yyy),就绕过了Webpack DevServer,请求直接发往该完整URL对应的服务器。DevServer的proxy配置不会和这个请求交互,因此无法将它代理到你配置的目标服务器。
请求改造
于是再改回需要代理的接口,并对项目逻辑进行一些改造,因为默认的网络库会拼接url,这里做一个判断,将需要代理的域名和代理的字符作为一组值保存起来。
如果匹配中需要代理的需求,并用前缀来替换。
// 本地环境,需要将代理的接口剔除域名,并拼接代理前缀
if (process.env.NODE_ENV === 'development') {
const proxyObj = {
'https://xxxx.cn': '/proxyApi',
};
const proxyKeys = Object.keys(proxyObj);
for (let i = 0; i < proxyKeys.length; i++) {
const host = proxyKeys[i];
if (option.url.includes(host)) {
const prefix = proxyObj[host];
option.url = option.url.replace(host, prefix);
}
}
}
这样就可以将接口请求拼接为 https://xxxx.con 域名的全部替换为指定前缀,这样这部分的请求就都会走代理。!

很惭愧,虽然早就知道 webpack 的 proxy 配置解决本地跨域问题,但确实很少自己去配置,一般是后端解决掉跨域问题或者项目里的自带里处理方案,所以真正到自己配置的时候多少有点迷糊了。
抽丝剥茧:详述一次DevServer Proxy配置无效问题的细致排查过程的更多相关文章
- webpack devserver proxy 配置以及react多页面
github地址: https://github.com/yangstar/React-antd-webpack-dev-server var webpack = require('webpack') ...
- Webpack代理proxy配置,解决本地跨域调试问题,同时允许绑定host域名调试
Webpack代理proxy配置,解决本地跨域调试问题,同时允许绑定host域名调试 会撸码的小马 关注 2018.05.29 17:30* 字数 212 阅读 1488评论 0喜欢 2 接到上一章, ...
- Charles使用问题, iOS7的http代理(http proxy)配置不生效问题
Charles配合iOS7使用时, 发现iOS7的http代理(http proxy)配置不生效, 代理信息写完后, 系统没有自动保存. 解决方法: 将些wifi忽略, 重新连接, 再配置代理就好了.
- 自学Zabbix13.2 分布式监控proxy配置
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix13.2 分布式监控proxy配置 分为两部分: 安装proxy 配置proxy ...
- spring security+cas(cas proxy配置)
什么时候会用到代理proxy模式? 举一个例子:有两个应用App1和App2,它们都是受Cas服务器保护的,即请求它们时都需要通过Cas 服务器的认证.现在需要在App1中通过Http请求访问App2 ...
- hyper-v Centos7 网卡配置无效
环境: Win 10 Hyper-v 安装虚拟机:Centos 7 遇到问题: 网络配置无效,使用命令“ip addr” 网卡没有出现在列表中,显示了一个奇怪的网卡名字如“enp0s010f”,配置文 ...
- require.js 加载 js 文件 404 处理(配置无效)
main.js 是 配置文件,data-main 是异步加载,如果在main.js未加载完成的时候,使用了require去加载文件,就会导致配置无效 main.js
- zabbix proxy配置实战案例
zabbix proxy配置实战案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.zabbix proxy概述 上一篇博客我们分享了zabbix agent有两种工作模式,即 ...
- 关于vue.config.js 的 proxy 配置
关于vue.config.js 的 proxy 配置有的同学不怎么明白项目里面有的配置了 pathRewrite 地址重写,有的又没有进行配置?/* * proxy代理配置的说明 * *接口例子:/z ...
- 框架源码系列九:依赖注入DI、三种Bean配置方式的注册和实例化过程
一.依赖注入DI 学习目标1)搞清楚构造参数依赖注入的过程及类2)搞清楚注解方式的属性依赖注入在哪里完成的.学习思路1)思考我们手写时是如何做的2)读 spring 源码对比看它的实现3)Spring ...
随机推荐
- 提高生产力!这10个Lambda表达式必须掌握,开发效率嘎嘎上升!
在Java8及更高版本中,Lambda表达式的引入极大地提升了编程的简洁性和效率.本文将围绕十个关键场景,展示Lambda如何助力提升开发效率,让代码更加精炼且易于理解. 集合遍历 传统的for-ea ...
- #树形dp#洛谷 4395 [BOI2003]Gem 气垫车
题目 给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数 唯一的限制条件是相邻的两个结点不能标上相同的权值,要求一种方案,使得整棵树的总价值最小. 分析 每个结点的权值最大可能为 \(\l ...
- #分治,Kruskal#洛谷 3206 [HNOI2010]城市建设
题目 动态改边权求最小生成树 \(n\leq 2*10^4,m\leq 5*10^4,q\leq 5*10^4\) 分析 乍一看是线段树分治,但有一个很大的问题就是局部的Kruskal不一定是最后的选 ...
- #dp、树状数组#JZOJ 3859 孤独一生
题目 将\(n\)座山(给定高度和\(n\))分成两个集合(按照原次序排列),然后在两个集合前加入海拔为0的平地 现在YC--一名julao,会两次从平地开始沿竖直方向跳到下一座山(别问我怎么做到的) ...
- OpenHarmony 3.2 Beta多媒体系列——视频录制
一.简介 媒体子系统为开发者提供了媒体相关的很多功能,本文针对其中的视频录制功能做个详细的介绍.首先,我将通过媒体子系统提供的视频录制Test代码作为切入点,给大家梳理一下整个录制的流程. 二.目录 ...
- .NET周刊【4月第1期 2024-04-07】
国内文章 一个程序员的编年史 https://www.cnblogs.com/lunacy/p/18117213 作者拥有15年软件开发经验,曾在多家公司工作,项目和团队起伏充满变数.2007年,在太 ...
- Linux-搭建内网yum源
部署要求: 服务器:CentOS7 YUM源:阿里云 空间要求:CentOS6+CentOS7 50G,考虑后期更新预留,LVS空间100G 1.在服务器配置CentOS7的yum源和CentOS6的 ...
- 在python中实现二叉树
二叉树设计 定义节点类 class Node: # 修改初始化方法 def init(self,value): self.value = value # 节点值 self.left = None # ...
- c# apollo订阅与发布(一)(迁)
前言 apollo 翻译过来是阿波罗的意思,准确的说是:apache apollo,看了apache基本可以放心,因为它不像微软. 安装 下面我以windows 为例. https://activem ...
- 不常用的技能-【手动编译java类】
jdk版本:1.7 冒号分割jar包,1.8 分号分割jar包 javac -classpath fastjson-1.2.24.jar:jedis-2.9.0.jar Test.javajava - ...