自集成式 HTTP 代理方案

前言

大部分程序员,想必都会有一个常用的抓包代理工具;  

但在座的各位,可曾见过这样一款集成在 Web 应用中的代理工具?

,时长00:45

它是明显区别于传统代理工具的,有以下特性:

  • 零安装、零配置,Web 点击即用、APP 扫码即用;(不是开盖即食,而是直接喂到嘴里
  • 分享 URL 链接(或二维码),即可远程调试 HTTP 协助他人或调试移动设备
  • 用户可远程相互共享代理配置,无需手动导入导出

以一个场景举例

  1. 你是一个前端开发,当后端接口还没准备好(或有 Bug 时),产品或设计师想体验效果
  2. 传统办法,你配好接口 Mock,让产品使用你的设备体验
  3. 当前方案,你配好接口 Mock,发一个 URL 链接给产品即可远程体验

它的原理是将代理服务与应用(Web 网页或 APP)集成,从而大幅降低用户(研测产运)的使用成本。

图片

应用集成代理服务对应的 SDK,自动转发请求到代理服务

传统代理工具的主要成本

  • 下载安装代理程序,甚至收费
  • 配置系统代理(移动端更烦)、https 证书
  • 同事之间共享代理规则(手动导入导出文件)

这些成本带来各种烦恼,也将非技术岗位拒之门外。  

场景:中午去吃饭的时候,手机突然断网;原来是刚刚网络调试,配置了系统代理!

笔者曾尝试过多款代理工具,始终有不满意的地方,多年前在自己的开源项目 [Erra][1] 中探索新的代理方案,仍然不满意,遂放弃。  

现将 Erra 的代理服务与工作中的应用集成,借鉴 [whistle][2] 的规则,再重新实现 UI 交互,终觉尚可。

以下对比笔者曾长期使用过的代理工具。

Charles

LightProxy

FF-Proxy

下载安装 APP

配置操作系统代理

安装信任 HTTPS 证书

Mock 方式

UI

文本规则

UI + 文本规则

Mock 规则共享

导出规则文件

复制规则文本

在线分享

远程调试

通用 HTTP 请求代理

安装部署服务

该方案改进了工作中高频对特定应用(公司产品的域名、APP) 进行网络调试的体验和效率;

该方案是一个增强型能力,与通用代理工具(Charles、LightProxy 等)没有任何冲突,不会影响习惯使用通用代理工具的同学。

接下来介绍该方案的技术实现思路。

方案原理概览

图片

总结分为四个部分

  1. 与应用集成,将请求转发到代理服务,由代理服务转发请求到目标服务
  2. 代理服务提供网络调试界面(UI),允许用户查看网络请求、配置 Mock 规则
  3. 代理服务记录请求,并同步到 UI 界面
  4. 代理服务在转发请求前、收到响应后,按 Mock 规则篡改请求内容

应用集成

与应用集成是当前方案区别与代理工具的根本所在,也是能实现零安装、零配置便捷性的原因

集成是将代理服务对应的 SDK 注入到业务系统(网页或 APP)中,SDK 会拦截并转发请求到代理服务。

集成 SDK 的方式介绍以下两种,更多拦截注入技巧请阅读 [​​Web 终极拦截技巧(全是骚操作)​​][3]。

自动注入 SDK

1. 配置 DNS 使 `ff-*` (混合泛解析)指向代理服务,代理转发 html 请求时自动注入 SDK

  • 注入脚本示例`resp.body.replace('<head>', '<head><script src="/ff-sdk.js"></script>')`

2. 假设目标域名为 `live.bilibili.com`,使用 `ff-live.bilibili.com` 访问代理服务即可自动注入

该方式无需业务项目对接,适合多个域名(系统)需要接入的场景。

注:ff-sdk.js 即需要注入,在客户端环境运行的的 SDK

 手动注入 SDK

手动往前端项目的 HTML 中写入`<script src="/ff-sdk.js"></script>`

,或打包构建时自动注入。

接入项目较少,或没有 DNS 配置权限,则可采用该方式接入。

拦截转发请求

向页面注入 SDK(`ff-sdk.js`)后, 根据 URL Query 参数决定是否开启拦截转发请求。  

若 URL 参数包含 `ff-proxy-id` 即启动拦截转发,参数值是随机生成 id,用于隔离不同用户数据。  

拦截转发的实现原理是重写 `fetch, xhr, WebSocket` 等对象,将请求转到代理服务,如何转发请看下文请求变换协议;  

另外还需要重写 `open, a, iframe` 的目标链接,确保页面跳转(或嵌入)场景也能继续保持 URL 前缀(`ff-`)和 Query 参数(`ff-proxy-id`) 的状态。

// 接口性能监控,打开 https://example.com/, 在控制台执行以下代码
const _fetch = window.fetch;
window.fetch = (...args) => {const startTime = performance.now();return _fetch(...args).finally(() => {console.info('接口耗时:', Math.round(performance.now() - startTime), 'ms');});
};await fetch('//example.com');

重写系统 API 以实现拦截的更多技巧,请阅读 [​​Web 终极拦截技巧(全是骚操作)​​][3]。

移动端 APP 支持

1. 向网络库注册一个拦截器

2. 扫描特制的二维码后,拦截器开始转发请求

3. 扫码后 APP 还需要修改 WebView 容器的 URL,添加前缀(`ff-`)和 Query 参数

   - 前缀和参数的内容在二维码中获取

HTTP 请求变换协议

SDK 拦截 HTTP 请求转到代理服务,然后还原再转到目标服务,其关键在于变换与还原请求的协议

原始请求,直接指向目标服务 (_以 curl 风格描述请求_)

`curl -v https://api.live.bilibili.com/test`

URL 添加前缀 `ff-` 请求会转到代理服务,因为代理服务注册了 DNS 混合泛解析规则`ff-*`;  

再添加 HTTP Header `x-ff-proxy-id` 用于隔离不同用户的数据。

`curl -v 'http://ff-api.live.bilibili.com/test' -H 'x-ff-proxy-id: xxx'`

代理服务移除 URL 中的前缀与 Header,即还原成原始请求,再发送给目标服务;  

同时,根据 `x-ff-proxy-id` 将该请求同步给对应 UI 界面。

代理服务与 UI 交互

图片

代理服务作为远程中心节点,跟客户端(UI界面)使用 WebSocket 保持通信,代理服务会按照 `ff-proxy-id` 只同步当前用户的数据,数据包括抓包记录、Mock 规则、资源。

资源是用来管理内容较大的 Request、Response body,方便用于 Mock 替换 HTTP 内容。

通过 URL `ff-proxy.bilibili.com/ui/` 即可访问 UI 界面。

图片

抓包

代理服务每次代理请求都会根据 `ff-proxy-id` 的值,将请求内容 copy 一份发送给客户端,这就实现了远程调试。  

所以该方案实现远程调试是非常自然的,传统代理工具相对麻烦是因为它工作在用户的设备上,远程调试必须通过手动设置系统代理来实现连接。

比如,手机上访问接口  

`curl -v 'http://ff-api.live.bilibili.com/test' -H 'x-ff-proxy-id: xxx'`

任何用户在任何设备上打开了 `ff-proxy.bilibili.com/ui/xxx` 页面, 即可远程看到请求的详细内容。

图片

Mock 规则

代理服务还能接受客户端提交的 Mock 规则,在转发请求前、收到响应后,按规则篡改请求内容。

支持对 HTTP 请求内容的基本修改(添加、删除、替换),即可满足绝大部分 Mock 诉求;  

HTTP 请求内容指

  • Request: URL、Header、Body,
  • Response: StatusCode、Header、Body

图片

规则借鉴了 [whistle][2] 并做了大量简化,同时也提供 UI 配置以降低使用门槛。

图片

规则解析

  1. 定义规则语法
  2. 使用 [peggy][4] 按语法将字符串解析为 AST(抽象语法树)
  3. 将 AST 转换为 js 函数实现
  4. 函数会检测代理的请求是否命中规则,命中后按规则描述篡权请求内容

规则相对简单,使用语法解析是为了保持扩展性,字符串处理多写几个条件判断也能实现。

数据存储

数据(Mock 规则、资源)存储在浏览器的 indexedDB 中,每次连接时同步到代理服务进行解析;  

所以,代理服务是一个干净的、只维持临时状态的服务,非常方便部署与扩展。

相对传统代理的缺点

方案的优点写在了文章开头,这里有必要总结一下缺点,感兴趣的同学自行斟酌。

  • 需要部署、维护代理服务
  • 该方案以系统维护者的一次性部署成本,交换多个用户安装、配置软件的成本
  • 有一定侵入性
  • 该方案不是一个透明的中间节点,会修改业务系统的行为(注入 SDK 拦截转发)
  • PS:DNS 集成方式,可让业务系统无感自动接入,最小化影响
  • 不具备通用性 
  • 该方案无法调试系统网络请求,无法调试未接入的业务系统、APP

总结

该方案的原理是将代理服务与应用集成,从而改进了工作中高频对特定应用进行网络调试的体验和效率。

所以,实施的前提是:一定的团队规模让(效率体验改进)收益大于付出(代理系统部署维护成本)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解析流中 apts 与 vpts的分布

流中 apts 与 vpts的分布情况&#xff0c;同时使用图显示出来 一&#xff0c;最好的方式是使用EasyICE 来查看&#xff0c;这个自动化工具是很好用的&#xff1a; 二&#xff0c; 当EasyICE不能打出理想的数据的时候&#xff0c;可以自己来提取数据&#xff0c;画出对应的图&a…

tomcat--安装

官网&#xff1a;Apache Tomcat - Welcome! 官网文档&#xff1a;Apache Tomcat 8 (8.5.100) - Documentation Index 帮助文档&#xff1a;Apache Tomcat Home - Apache Tomcat - Apache Software Foundation FAQ - Apache Tomcat - Apache Software Foundation yum安装 查…

OpenNJet:引领下一代云原生应用引擎

文章目录 一、前言二、什么是OpenNJet 应用引擎三、OpenNJet的优势3.1 性能无损动态配置3.2 灵活的CoPilot框架3.3 支持HTTP/33.4 支持国密3.5 企业级应用3.6 高效安全 四、centos 安装4.1 生成njet.repo4.2 更新yum 缓存4.3 安装 njet 或 njet-otel 五、OpenNJet配置与部署5.1…

岩土工程监测仪器之一:振弦采集仪的工作原理解析

岩土工程监测仪器之一&#xff1a;振弦采集仪的工作原理解析 河北稳控科技振弦采集仪是岩土工程监测中常用的一种仪器&#xff0c;用于测量地面、结构物或其他物体的振动情况。它通过感应振弦的振动来获取相关的数据&#xff0c;进而分析和评估土壤、地基或结构物的稳定性和安…

用户登录认证和权限授权(SpringSecurity、JWT、session)

文章目录 前言一、登录认证1. 问题引入2. Session2.1 实现原理2.2 过滤器Filter2.3 上下文对象 3. JWT3.2 实现步骤3.3 拦截器 HandlerInterceptorAdapter3.4 上下文对象 4. Session VS JWT 二、权限授权1. 权限类型1.1 页面权限&#xff08;菜单项权限&#xff09;1.2 ACL模型…

牛客热题:二叉树的前序遍历

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;二叉树的前序遍历题目链接方法一…

灵卡科技HDMI音视频采集及H.264编码一体化采集卡—LCC260

推荐一款由灵卡科技倾力打造的高品质HDMI音视频采集卡——LCC260。以创新的技术&#xff0c;精湛的工艺和卓越的性能&#xff0c;为您提供全方位的音视频解决方案。 LCC260是一款集HDMI音视频采集与H.264编码于一身的全功能采集卡。它的输入端配备了最先进的HDMI 1.4a标准接口&…

tab 滑动小案例

效果&#xff1a; 代码&#xff1a; <template><view class"content"><view class"tab"><view v-for"(item,index) in dataList" :key"index" class"tab_item" click"slideTab(index)">…

简单有效的数据加密方法你知道几个?

1. 文件和邮件加密 利用华企盾DSC数据防泄密系统&#xff0c;企业可以实现文件和邮件的加密。系统提供了一键式的文件加密解决方案&#xff0c;确保敏感信息在电子邮件中传输时得到安全保护&#xff0c;即使邮件被截获&#xff0c;内容也无法被未授权人员阅读。 2. 端到端数据…

UNetformer实现遥感城市场景影像的高效语义分割

UNetFormer:一种类似UNet的转换器,用于遥感城市场景影像的高效语义分割,ISPRS。此外,还包括用于卫星、航空图像和无人机图像分割。 本文选取的是WHU-Building-DataSets。数据集[1]包含了从新西兰基督城的航空图像中提取的超过220,000个独立建筑,图像被分割成了8189个5125…

Lambda 表达式详解

LAMBDA ⚪ λ 希腊字母表中排序第十一位的字母, 英语名称为Lambda ⚪ 避免匿名内部类定义过多 ⚪ 其实质属于函数式编程的概念 ⚪ 也可称为闭包 ⚪ Lambda允许把一个函数作为方法的参数&#xff08;函数作为参数传递进方法中&#xff09;。 Lambda是在jdk8之后出现的所以现…

FloodFill算法---BFS

目录 一、前言 二、算法模板套路 2.1 创建所需的全局变量&#xff1a; 2.2 BFS模板&#xff1a; 2.3 细节处理&#xff1a; 三、例题练习 3.1 例题1&#xff1a;图像渲染 3.2 例题2&#xff1a;岛屿数量 3.3 例题3&#xff1a;岛屿的最大面积 3.4 例题4&#xff1a;被…

人工智能应用正在改变我们的生活

在这个AI蓬勃发展的时代&#xff0c;你如何使用人工智能&#xff1f;如果您认为还没有&#xff0c;请再想一想。人工智能已经为我们的许多日常活动提供了动力&#xff0c;尽管您可能还没有有意将其用作工具&#xff0c;但这种情况可能会在不久的将来发生变化。随着顶尖科技公司…

如何更换远程服务器的Python版本

目录 前言 正文 尾声 &#x1f52d; Hi,I’m Pleasure1234&#x1f331; I’m currently learning Vue.js,SpringBoot,Computer Security and so on.&#x1f46f; I’m studying in University of Nottingham Ningbo China&#x1f4eb; You can reach me by url below:My Blo…

简单的mysql主从复制搭建

文章目录 准备工作用Docker安装MySQL主库配置【192.168.13.32】从库配置【192.168.13.108】小结 准备工作 用虚拟机提前准备两台服务器&#xff0c;并且在服务器中分别安装好MySQL&#xff0c;服务器的信息如下&#xff1a; 数据库IP主节点192.168.13.32从节点192.168.13.108…

IDEA终端环境配置

Idea如何配置终端&#xff1b; 第一步&#xff1a;找到我的电脑&#xff0c;右击——属性——高级系统设置——环境变量 先配置path: 在后面加入&#xff1a;C:\Program Files (x86)\Java\jdk1.7.0_75\bin&#xff08;每个人放置jdk的位置不同。&#xff09; 新建classpath:…

【MySQL数据库】初步认识数据库,实现基本操作

在信息爆炸的今天&#xff0c;数据无处不在&#xff0c;它们构成了互联网世界的基石。但数据本身若未经有效组织和管理&#xff0c;就如同散落在沙滩上的珍珠&#xff0c;难以发挥其真正的价值。这时&#xff0c;“数据库”这一概念便如同一根线&#xff0c;将这些珍珠串联起来…

【Redis】Redis 主从集群(一)

为了避免 Redis 的单点故障问题&#xff0c;可以搭建一个 Redis 集群&#xff0c;将数据备份到集群中的其它节点上。若一个 Redis 节点宕机&#xff0c;则由集群中的其它节点顶上 1.主从集群搭建 Redis 的主从集群是一个“一主多从”的读写分离集群。集群中的 Master 节点负责…

数字人解决方案——AniPortrait音频驱动的真实肖像动画合成

概述 在当今数字化时代&#xff0c;将静态图像和音频素材转化为动态、富有表现力的肖像动画&#xff0c;已经成为游戏、数字媒体、虚拟现实等多个领域的重要技术。然而&#xff0c;开发人员在创建既具有视觉吸引力又能保持时间一致性的高质量动画框架方面面临着巨大挑战。其中…

k8s endpoint

Endpoint Service 并不是和 pod 直接相连的&#xff0c;Endpoint 介于两者之间。Endpoint 资源就是暴露一个服务的 IP 地址和端口的列表。 虽然在 spec 服务中定义了 pod 选择器&#xff0c;但在重定向传入连接时不会直接使用它。选择器用于构建 IP 和端口列表&#xff0c;然…