自集成式 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

总结

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

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

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

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

相关文章

解决AdaptiveAvgPool2d部署算子不支持问题

一、Pytorch中AdaptiveAvgPool2d函数详解 torch.nn.AdaptiveAvgPool2d()接受两个参数&#xff0c;分别为输出特征图的长和宽&#xff0c;其通道数前后不发生变化。如以下&#xff1a; self.global_avgpool nn.AdaptiveAvgPool2d(1) # 输出N*C*1*1 self.global_avgpool …

AcWing166. 数独-DFS剪枝与优化

题目 思路 思考问题&#xff1a;搜索顺序->考虑剪枝搜索顺序&#xff1a;先随意选择一个空格子&#xff0c;枚举该格子可填写的数字&#xff0c;当所有格子都填完的时候&#xff0c;说明可以退出了剪枝&#xff1a; 优化搜索顺序&#xff1a;随意选择一个空格子&#xff1a…

【讲解下iCloud如何高效利用】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

C++实战演练---负载均衡在线oj项目 || 编译服务模块设计

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 前言 上一篇预热文章简单说过我们的编写思路&#xff0c;首先要实现的是编译功能&#xff0c;那么在编译功能版块中&…

Java面试八股之float和double的区别

Java中float和double的区别 存储空间与精度&#xff1a; double&#xff1a;占据64位&#xff08;8字节&#xff09;存储空间&#xff0c;属于双精度浮点数。它可以提供较高的精度&#xff0c;通常能够精确表示大约15到17位十进制数字&#xff0c;适合用于需要较高精度计算或…

SSM【Spring SpringMVC Mybatis】—— Spring(二)

如果对于Spring的一些基础理论感兴趣可见&#x1f447; SSM【Spring SpringMVC Mybatis】—— Spring&#xff08;一&#xff09; 目录 1、Spring中bean的作用域 1.1 语法 1.2 四个作用域 2、Spring中bean的生命周期 2.1 bean的生命周期 2.2 bean的后置处理器 2.3 添加后…

upload-labs靶场通关详解(1-15)

1.pass-01 查看源代码 是js&#xff0c;属于前端校验 可以通过禁用js来上传文件 2.pass-02 根据提示是MIME绕过 MIME&#xff1a;是设定某种扩展名的文件 用一种应用程序来打开的方式类型&#xff0c;当该扩展名文件被访问的时候&#xff0c;浏览器会自动使用指定应用程序来…

OpenAI发布新品GPT-4o,电影《HER》演绎的世界真的来了!

5月14日&#xff0c;OpenAI宣布推出最新旗舰生成式AI模型GPT-4o&#xff0c;它可以实时处理音频、视觉、并对文本进行推理。可以说这是一种全新的交互模式&#xff0c;它完美复刻电影《Her》的世界&#xff0c;标志着人工智能全感知时代的到来。 GpuMall智算云 | 省钱、好用、…

swiper 点击事件失效问题

在刚开始使用是 swiper 时&#xff0c;点击事件有时失效&#xff0c;这些个问题的原因是&#xff1a;swiper设置looptrue时&#xff0c;会生成虚拟slide进行填充&#xff0c;对这些虚拟slide元素进行操作是无效的。 简单粗暴的方法就是将 loop 置为 false ....................…

JVM面试题:85道JVM虚拟机面试题及答案

面试题 1 .简述Java堆的结构&#xff1f;什么是堆中的永久代(Perm Gen space)? JVM整体结构及内存模型 试题回答参考思路&#xff1a; 1、堆结构 JVM的堆是运行时数据区&#xff0c;所有类的实例和数组都是在堆上分配内存。它在JVM启动的时候被创建。对象所占的堆内存是由自…

开发测试必须知道的 10种 常见软件架构模式

你是否想知道企业大规模系统是如何设计的? 在软件开发开始之前&#xff0c;我们必须选择一个合适的架构&#xff0c;能提供所需的功能和质量特性。因此&#xff0c;在将架构应用到我们的设计之前&#xff0c;我们应该了解各种不同架构的特点。 01 什么是架构模式 根据维基百…

一文分享:抖音外卖城市合伙人如何申请合作?

在当今数字化时代&#xff0c;外卖和团购业务蓬勃发展&#xff0c;商家们纷纷寻求在多个平台上拓宽销售渠道&#xff0c;以获取更多的订单和利润&#xff0c;这也给创业者提供创来机会。在这其中&#xff0c;抖音外卖作为一股新势力&#xff0c;自然吸引了众多创业者的目光&…

解锁客户需求密码:银行业数据分析在业务决策中的关键作用

一、引言 在数字化和大数据时代的浪潮下&#xff0c;银行业正经历着前所未有的变革。作为数据分析领域的资深专家&#xff0c;我深知数据分析在银行业务发展中的重要性和价值。本文将从银行业数据分析的角度出发&#xff0c;深入探讨相关业务场景下的数据分析应用&#xff0c;…

斥巨资!韩国力撑芯片产业

KlipC报道&#xff1a;韩国为加强本国半导体产业竞争力&#xff0c;将推进一项超过10万亿韩元的支持计划。 大型科技公司微软、亚马逊和谷歌为了保持自己大型语言模型的竞争力&#xff0c;投入了大量的资金&#xff0c;全球对可生成AI应用的需求在不断增长&#xff0c;市场上对…

Vision Mamba 代码调试---Pycharm+AutoDL

《AutoDL使用手册》 1. 服务器租用与配置 先上项目链接&#xff1a; GitHub - hustvl/Vim: Vision Mamba: Efficient Visual Representation Learning with Bidirectional State Space Model 1.1 服务器租用与配置 根据环境要求&#xff0c;去租一个服务器&#xff1a;AutoDL算…

Ajax 学习

文章目录 1. 前置知识1.1 ajax 介绍1.2 XML 简介 2. AJAX 学习2.1 AJAX基础学习&#xff08;1&#xff09;AJAX的特点&#xff08;2&#xff09;AJAX 初体验&#xff08;3&#xff09;服务端响应json 数据 2.2 IE 缓存问题2.3 请求超时和网络异常2.4 手动取消请求2.5 重复请求2…

鸿蒙 DevEcoStudio:用户名密码获取保存

【使用首选项实现用户名密码保存获取】 打开src/main/ets/entryability路径下的EntryAbility.ts文件 在 export default class EntryAbility extends UIAbility {onCreate(want, launchParam) {hilog.info(0x0000, testTag, %{public}s, Ability onCreate);下边添加内容&…

【JVM】调优工具

这里简单介绍一下各种调优用到的工具 一&#xff0c;环境准备 首先我们需要准备好Java环境&#xff0c;和win上的jdk环境&#xff08;图形化界面如jconsole只有jdk中有&#xff09;。 有这样一个类Prolem&#xff0c;每个线程都会带来100个垃圾对象&#xff0c;线程new完100…

智慧公厕,提升公共厕所管理效率的信息化变革

现代社会中&#xff0c;公共厕所的管理成为一个不可忽视的问题。随着城市化进程的加快&#xff0c;人们对公厕的需求日益增加&#xff0c;但公厕的管理却面临诸多困难。为了解决这一问题&#xff0c;智慧公厕应运而生&#xff0c;通过信息化的变革&#xff0c;提高公厕的管理效…

QT函数整理

目录 1. 适应高分辨率函数 1. 适应高分辨率函数 自动适应调整设备安装QT的UI分辨率&#xff1a; QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 加载位置&#xff1a;