抽丝剥茧:详述一次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 配置解决本地跨域问题,但确实很少自己去配置,一般是后端解决掉跨域问题或者项目里的自带里处理方案,所以真正到自己配置的时候多少有点迷糊了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/618193.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ARM架构安全特性概览

安全之安全(security)博客目录导读 目录 一、跨行业计算安全 二、Arm架构安全特性的益处 三、安全威胁与缓解 四、防御执行技术 五、隔离技术 六、通用平台安全服务 七、标准安全 API 八、PSA安全标准认证 一、跨行业计算安全 从一开始&#xff0c;Arm 生态系统一直是…

VS项目Debug下生成的EXE在生产机器上运行

使用Visual Studio开发应用程序时&#xff0c;为了临时在非开发机上看一下效果&#xff0c;就直接把Debug下的文件全部拷贝到该机器上&#xff0c;直接双击exe运行。双击之后&#xff0c;没有直接打开应用程序&#xff0c;而是弹出了一个Error弹框。  赶快在网上搜了一遍&…

Ardupilot开源代码之Rover上路 - 后续1

Ardupilot开源代码之Rover上路 - 后续1 1. 源由2. 问题汇总2.1 问题1&#xff1a;飞控选择2.2 问题2&#xff1a;飞控安装位置和固定2.3 问题3&#xff1a;各种插头、插座配套2.4 问题4&#xff1a;分电板缺陷2.5 问题5&#xff1a;电机编码器接线及正反向问题2.6 问题6&#x…

什么是等保2.0,相对等保1.0有哪些变化,支撑等保2.0的标准文档有哪些?

1. 等保1.0、等保2.0业界定义 等保1.0&#xff1a;以1994年2月18日年国务院颁布的 147 号令《中华人民共和国计算机信息系统安全保护条例》为指导标准&#xff0c;以2008年发布的《GB/T22239-2008 信息安全技术 信息系统安全等级保护基本要求 》为指导的网络安全等级保护办法。…

向量数据库:Chroma

目录 一、Chroma 介绍 二、安装 Chroma 2.1 创建虚拟 python 环境 2.2 安装 Chroma 2.3 运行 Chroma 三、Backend API 一、Chroma 介绍 Chroma是一个开源的嵌入式数据库。Chroma通过使知识(knowledge)、事实(facts)和技能(skills)可插拔&#xff0c;从而简化了大型语言模…

小猫咪邮件在线发送系统源码,支持添加附件

一款免登录发送邮件&#xff0c;支持发送附件&#xff0c;后台可添加邮箱,前台可选择发送邮箱 网站数据采取本地保存&#xff0c;所以使用前请给网站修改权限&#xff0c;否则很多功能将无法使用 安装教程&#xff1a; 1.上传服务器或者主机 2.登录后台&#xff0c;添加发送…

FCOS长文详解

1. 概述 FCOS是一种one-stage、全卷积&#xff08;Fully Convolutional&#xff09;结构的目标检测模型&#xff0c;发表于2019年ICCV。&#xff08;什么是one-stage&#xff1f;&#xff09; 论文原地址&#xff1a;https://arxiv.org/abs/1904.01355 作者源码&#xff1a;ht…

本地项目上传到gitee

1. 新建仓库&#xff0c;不要勾选 2. git init git add . git commit -m "test" git remote add origin 【url】 git push --set-upstream origin master

【Java】:方法重写、动态绑定和多态

目录 一个生动形象的例子 场景设定 1. 方法重写&#xff08;Method Overriding&#xff09; 2. 动态绑定&#xff08;Dynamic Binding&#xff09; 3. 多态&#xff08;Polymorphism&#xff09; 归纳关系&#xff1a; 重写 概念 条件 重写的示例 重载与重写的区别 …

STM32 | STC-USB驱动安装Windows 10(64 位)

Windows 10&#xff08;64 位&#xff09;安装方法 由于 Windows10 64 位操作系统在默认状态下&#xff0c;对于没有数字签名的驱动程序是不能安装成功的。所以在安装 STC-USB 驱动前&#xff0c;需要按照如下步骤&#xff0c;暂时跳过数字签名&#xff0c;即可顺利安装成功。…

回归预测 | Matlab实现GA-LSSVM遗传算法优化最小二乘支持向量机多输入单输出回归预测

回归预测 | Matlab实现GA-LSSVM遗传算法优化最小二乘支持向量机多输入单输出回归预测 目录 回归预测 | Matlab实现GA-LSSVM遗传算法优化最小二乘支持向量机多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 Matlab实现GA-LSSVM遗传算法优化最小…

纯CSS实现步骤条

纯CSS实现纵向Steps步骤条效果 效果图 实现思路 步骤条是一种用于引导用户按照特定流程完成任务的导航条&#xff0c;在各种分步表单交互场景中广泛应用。步骤条通常由编号、名称和引导线三个基本要素组成。本文中要实现的是一个简单的步骤条&#xff0c;包含上述三个基本要素…

Python爬虫实战:爬取【某旅游交通出行类网站中国内热门景点】的评论数据,使用Re、BeautifulSoup与Xpath三种方式解析数据,代码完整

一、分析爬取网页&#xff1a; 1、网址 https://travel.qunar.com/2、 打开网站&#xff0c;找到要爬取的网页 https://travel.qunar.com/p-cs299979-chongqing进来之后&#xff0c;找到评论界面&#xff0c;如下所示&#xff1a;在这里我选择驴友点评数据爬取点击【驴友点评…

天下大爱唯母爱

岁月轮转&#xff0c;人生寻常&#xff0c;又逢一年母亲节。作为子女&#xff0c;这是所有人都参与节日&#xff0c;也是每一位母亲在繁忙日常中&#xff0c;一个短暂的休息&#xff0c;停下手中的忙碌&#xff0c;听孩子的一声祝福&#xff1a;妈妈辛苦了&#xff0c;母亲节快…

树莓派4B-搭建一个本地车牌识别服务器

实现目标&#xff1a; 一、设备自启后能够获得服务的ip与端口号&#xff0c;用于计算机连接设备&#xff1b; 二、计算机可以通过服务ip与端口访问设备服务&#xff1b; 三、上传需要处理的数据&#xff0c;返回结果反馈给用户&#xff1b; 四、上传到服务器的数据不会导致设备…

车载测试系列:CAPL脚本语法

HFP测试内容与测试方法 2.3 接听来电&#xff1a;测试手机来电时&#xff0c;能否从车载蓝牙设备和手机侧正常接听】拒接、通话是否正常。 1、预置条件&#xff1a;待测手机与车载车载设备处于连接状态 2、测试步骤&#xff1a; 1&#xff09;用辅助测试机拨打待测手机&…

本地电脑hosts强制解析指定IP的方法

网站接入CDN后&#xff0c;很多时候需要本地强制解析回源查看状态&#xff0c;比如查看是不是源服务器故障&#xff0c;网站修改是否正确&#xff0c;网站更新是否及时&#xff0c;故障查看是CDN问题还是源服务器问题&#xff0c;都需要hosts回源。 今天云加速教大家如何本地电…

AI工具摸索-关于写作(1)

虽然人工智能工具非常多,但是如果想要成为生产力,能达标的工具仍然非常少,除了最常用的chatgpt,其他的工具真的能达标吗,这篇文章主要就是对比市面上的一些工具&#xff0c; 但我这个人非常执拗,我认为作为生产力工具的功能必然是可以真正帮助我们的,而不是说作为一个写作工具结…

docker部署springboot+Vue项目

项目介绍&#xff1a;后台springboot项目&#xff0c;该项目环境mysql、redis 。前台Vue&#xff1a;使用nginx反向代理 方法一&#xff1a;docker run 手动逐个启动容器 1.docker配置nginx代理 将vue项目打包上传到服务器上。创建文件夹存储数据卷&#xff0c;html存放打包…

【Dash】开始学习dash

安装Dash 网上很多安装dash的教程&#xff0c;不再赘述 开始Dash 一个dash页面的基本写法 # dash 的基本写法 import dash from dash import html,dcc,callback,Input,Output# 创建一个 dash 应用 app dash.Dash()# 定义布局&#xff0c;定义一个输入框和一个输出框 app.l…