目录
背景
前两天用 Charles 调试 Java 应用内发出的 HTTPS 请求,遇到了点儿问题,所以花了点儿时间研究 Charles 这种工具的工作原理。
Q:为什么有些 app 的 HTTP 请求能被 Charles 检测到,有些不能?
像我这种刚用 Charles 没多久的人,很可能会有这样的疑问:
- 为什么我在 Postman 上发的请求总是能在 Charles 中检测到?而 Java 应用中发起的请求必须配置 Charles 作为代理才能被检测到?
- 为什么我在 Chrome 上发出的请求有时候能在 Charles 中检测到,有时候不能?
- 为什么有时候需要安装 Charles 的 HTTPS 证书,才能在 Charles 中检测 HTTPS 流量,有时候就不需要?
这两天做了一些小实验,得出以下结论,见下节。
A:Charles 会修改系统默认代理设置,所以使用系统默认代理的 app 默认就能检测到
很多应用都会修改系统的默认代理。以 Windows 系统为例,在 Settings -> Network & Internet -> Proxy
中可以看到当前的系统代理配置:
如图,我现在的系统代理就是通过 Script address
一栏中指定的 PAC
配置文件实现的。
那么,运行 Charles 之后会发生什么呢?
可以看到,系统的默认代理配置被 Charles 修改了(需要退出重新进入才能看到刷新之后的代理配置):
127.0.0.1::8888
就是 Charles 代理服务运行的端口,所以现在凡是使用系统默认代理的应用,其请求都会由 Charles 代理,所以也就能被检测到了。
参考链接:
Display Windows’s proxy setting via CLI
How do I know what proxy server I’m using?
Postman 默认使用系统代理
首先来看 Postman。在 File -> Settings -> Proxy
中可以看到,Postman 默认勾选了 Use the system proxy
选项:
这就是为什么 Postman 中的请求默认就能被 Charles 检测到了。如果取消勾选该选项,Charles 就检测不到了。
Chrome 是否走系统代理,同样取决于配置
同理,Chrome 中也可以配置使用什么代理。我平时用一个 Chrome 插件来管理代理,有时候走系统默认代理,有时候不走,所以才会出现有时能被 Charles 检测到的情况。
JVM 默认不走系统代理
虽然我也没找到具体的文档,但可以肯定 JVM 默认是不走系统代理的。所以想要用 Charles 调试 Java 应用,才会需要加上类似于下面这样的代码:
System.setProperty("http.proxyHost", "127.0.0.1");
System.setProperty("https.proxyHost", "127.0.0.1");
System.setProperty("http.proxyPort", "8888"); // 8888 是 Charles 的默认端口号,请填写你使用的端口号
System.setProperty("https.proxyPort", "8888");
参考链接:使用 Charles 抓取 Java 应用内 HTTP/HTTPS 请求
先写到这里吧。