Skip to content

Instantly share code, notes, and snippets.

@banyudu
Last active November 24, 2021 07:04
Show Gist options
  • Save banyudu/f794ee6b58834ce41dc1ca230abbe6e3 to your computer and use it in GitHub Desktop.
Save banyudu/f794ee6b58834ce41dc1ca230abbe6e3 to your computer and use it in GitHub Desktop.
前端调试之网络代理

前端调试之网络代理

说到前端调试,脑海中是不是自然地就想到了源代码,想到开发环境等等概念?

它们是必需的吗?

移动应用调试时常有抓包的概念,它是什么?只能用来看日志吗?

本文带你了解一个新的前端应用调试思路,从工具应用到原理解析。希望能对读者有所启发,起到抛砖引玉的作用。

多环境的困局

软件开发过程中,为了保证质量,往往会将应用部署多个备份。即我们所熟知的生产环境、灰度环境、测试环境、开发环境等。

相应地,软件测试的过程也会分成多个阶段进行。

一般来说,测试人员会在各个不同的环境进行测试,但是开发人员总是会在本地进行修改。这个差异大多数时候不是什么问题,因为相同的代码会有相同的表现。

但是有的时候事情没那么简单,我们或多或少都遇到过一些这样的场景:

  1. 生产环境或测试环境能复现的问题,在开发人员本地环境中无法复现(如需要特定数据)。
  2. 开发环境、测试环境中上下游系统不稳定,导致无法正常使用。
  3. 开发环境、测试环境中上下游系统改版,无法保证与生产环境一致。
  4. 线上应用为微服务集群,难以在本地完美复制。

应用的架构越是复杂,想在本地搭建出一套100%一致的系统,就越困难。

试想下一个前端微应用,嵌入在门户首页中,本地运行正常,即使在生产环境独立访问也是正常的,只有嵌入在门户首页的时候才会出问题。这种情况的调试难度是较高的,使用传统方案很难解决,往往要靠猜测来实现。

这个时候,如果能随时将代码部署到生产环境进行调试,是不是就很容易啦?

当然,我们都知道这样是不现实,不负责的做法。生产环境不能用于调试。

然而,前端不一样!

这里,就需要提一下前端和后端应用的不同之处了。

前端与后端的区别

这里所指的前端,均为狭义前端,即运行在浏览器或原生应用WebView之中的,由HTML/CSS/JS/WASM等组成的Web应用。不包含Node.js及原生app。

前端与后端的区别,在于生产环境和运行环境的不统一。

后端环境

对于后端应用来说,生产环境即运行环境,现在一般是容器化的集群部署,通过Docker或类似工具提供稳定的运行环境。

虽然很多后端应用会有集群,分布式部署。但是一般来说,各个副本之间没有差别,代码和运行环境完全一致。

甚至很多无状态的后端应用,可以随时无缝替换彼此。

总结一下:后端应用运行在服务端,程序变更之后,会影响到很多用户。

前端环境

前端在部署上也类似于后端,无论是单节点还是多节点,返回的 HTML/CSS/JS等静态资源是始终一致的。

但是它的运行环境却千差万别。

有的运行在Chrome中,有的在Firefox中,有的在桌面端,有的在移动端。即使是同一个浏览器,还有不同版本的差别。

它们可以归结为一个环境:用户端。

因为是用户自己的环境,所以在它的上面再怎么折腾,也影响不到其它的用户。

这就使得我们可以直接调试 “生产环境”!

具体怎么做呢?这就回到了本文的题目中来了,网络代理。

网络代理调试

在说这个之前,先看一个“中间人攻击(MITM)”的示意图。

Man-in-the-middle attacks (MITM) and how to avoid them

图片来自于 https://dpsvdv74uwwos.cloudfront.net/statics/img/ogimage/man-in-the-middle-attack-how-avoid.png,侵删

网络代理调试,运用的就是这个攻击的原理。

简单来说,步骤如下:

  1. 通过上述的攻击原理,搭建一个“中间人”角色
  2. 篡改客户端(浏览器、APP等)的网络请求,使其指向 “中间人”
  3. 在“中间人”角色中,提供本地构建的代码用于调试。

那么具体来说有什么手段呢?

网络代理的手段

根据运行环境的不同,可采用的手段也不完全相同。

主要分为以下两类:

  1. 基于抓包工具实现的中间人攻击,适用于所有场景。特点是功能强,但配置复杂,易用性稍差。
  2. 基于浏览器插件实现的中间人攻击,适用于Chrome、Firefox浏览器及其它兼容Chrome插件的浏览器。特点是配置简单,但需要了解一些坑点,某些情况下需要代码配合。

两者的原理也相差较大,下面我分别介绍下对应的工具及原理。

基于抓包工具的中间人攻击

抓包工具有不少,有的需要付费使用,如老牌的Charles,有些虽然提供收费模式,但免费功能也凑合能用,如Mac上的ProxyMan。

它们的特点是:

  1. 需要安装证书才能攻击 HTTPS 资源。
  2. 浏览器端无感知,不需要修改代码配合。

这里我主要介绍ProxyMan。

ProxyMan 是一个macOS上的抓包工具,可以监控请求列表。

Proxyman Dashboard on macOS

也可以捕捉请求并设置自定义响应,映射到本地文件。

img

还可以映射到另一个URL:

Map Remote

基于浏览器插件的中间人攻击

因为一些安全方面的考量,浏览器插件并不能实现系统级别网络代理带来的无感知体验。

但是它可以为网络请求做重定向。

即虽然浏览器插件能篡改网络接口,但是在DevTools中会有记录,且会受到各种浏览器自身的限制,如混合内容限制等。

所以它的特点是:

  1. 存在混合内容限制(127.0.0.1除外)。
  2. 存在跨域限制。
  3. 对于前端应用的 webpack 分片,需要特殊处理(publicPath)。
  4. 配置和切换较为简单

浏览器插件可以使用 Resource Override。

img

网络安全

通过上面的例子也可以看出,在网络无保障的情况下,前端看到的内容很可能是不安全的。

这提醒我们,在安装证书,尤其是CA证书时,一定要谨慎。

不然很可能会受到中间人攻击而不自知。


以上就是通过网络代理(转发)调试前端应用的所有内容。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment