# Charles 从入门到精通

## 内容清单

- Charles 的简介
- 安装 Charles
- Charles 初始化设置
- 过滤网络请求 
- 截取HTTP/HTTPS数据 
- 模拟弱网环境 
- 修改网络请求 
- 修改服务器返回内容 
- 服务器压力测试 
- 反向代理 
- 解决与翻墙软件的冲突 



## Charles 的简介

**Charles** 是目前最主流的网络调试工具（Charles、Fiddler、Wireshark...）之一，对于一个开发者来说与网络打交道是日常需求，因此很多时候我们需要调试参数、返回的数据结构、查看网络请求的各种头信息、协议、响应时间等等。所以了解  Charles 并使用它

Charles 通过将自己设置为系统的网络访问代理服务器，这样所有的网络请求都会通过它，从而实现了网路请求的截获和分析。

Chareles 不仅可以分析电脑本机的网络请求（HTTP 和 HTTPS），还可以分析移动端设备的网络请求。

Charles 是收费软件，作者开发出这样一个方便开发者使用的伟大工具，我们鼓励使用正版软件，但是对于一些囊中羞涩或者学生来说，有破解版的更好，别担心，这些我都准备好了，下一个 section 会讲解如何下载安装。



## 安装 Charles

- 方式1：[ Charles 官网地址](https://www.charlesproxy.com/download/)，根据你的电脑操作系统选择合适的下载方式。此时下载下来的是需要收费的，不差钱的同学当然可以直接购买。[购买链接](https://www.charlesproxy.com/buy/)
- 方式2:按照方式1的方式去官网下载，然后下载相应 **[JAR包](https://pan.baidu.com/s/1QqSiEwMGIFrxwyKYg_6Kdw)**。这里以 MAC 为例，打 **Finder**，选择应用程序，选中 Charles，右击并选择“显示包内容”，看到 **Contents** 目录，点击进去选择 **Java** 文件夹，将下载下来的 **JAR包** 拖进去替换。至此，完成了 Charles 的破解。



## Charles 初始化设置

Charles 的工作原理是将自身设置为系统的代理服务器来捕获所有的网络请求。所以使用 Charles ，我们必须设置 Charles 为系统的代理服务器。

打开 Charles，当第一次启动的时候如果没有购买或者没有破解，会有倒计时，之后会看到软件的主界面，然后会请求你赋予它为系统代理的权限。点击授权会让你输入当前系统用户的密码。当然你也可以忽略或者拒绝该请求，然后等想要抓包的时候将它设置为系统的代理服务器。步骤：**选择菜单中的“Proxy” -> "Mac OS X Proxy"。**如下图：

![Charles在MAC的初始化](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/Charles-Setting.png)

之后你的电脑上的任何网络请求都可以在 Charles 的请求面板中看到



看看 Charles 的主界面

![Structure模式查看网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-004135@2x.png)
![Sequence模式查看网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-004435@2x.png)


- 图上红色圈1:这里代表所有网络请求的展示方式。分别名为 “Structure” 和 “Sequence”。
  - Structure 将所有的网络请求按照域名划分并展示
  - Sequence 将所有的网络请求按照时间排序并展示
- 图上红色圈2：一些的网络请求设置比如 HTTPS 以及端口等信息都在这个菜单栏设置
- 图上红色圈3：证书设置都在这里进行



## 过滤网络请求

由于 Charles 可以将电脑或者设置过的手机的所有网络请求捕获到，而且我们分析网络传输应该是针对某个特定的网络下的抓包分析，为了清楚明显地看到我们感兴趣的网络请求通常会用到 Charles 的**“过滤网络请求的功能”**。

- 方法1:在 Charles 主面板的左侧所有网络请求的下方可以看到看到一个 **”Filter“** 输入栏，在这里你可以输入关键词来筛选出自己感兴趣的网络请求。比如我想分析的网络请求来自于”www.baidu.com" 下，你可以在下面输入"baidu"即可。
  ![Filter 过滤网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-090550.png)

- 方法2:在 Charles 菜单栏的顶部会看到 “Proxy” 的选项，点击菜单栏选择 “Proxy” -> "Recording Settings" 。选择 “include”。看到面板上面有一个 “Add” 按钮，点击后在弹出的面板里面设置好我们需要分析的网络请求的**协议、主机名、端口、路径、参数**，当然你也可以只设置一些主要的信息，比如协议和主机名的组合。

  ![Recording Settings 过滤网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-090926.png)

- 方法3:一般打开 Charles 并设置好配置信息后（比如电脑本机或者设置过代理的手机）所有的网络请求都将在 Charles 的面板上显示，同时我们感兴趣的网络请求如果也在面板上显示的话，**“Structure”模式下**可以选中需要分析的网络请求，鼠标右击选择**“Focus”**。**“Sequence”模式下**可以在面板的网络请求显示面板的右下角看到一个**Focus**按钮，点击勾选后 Charles 只会显示你感兴趣的网络请求。

  ![Structure模式下Focus过滤网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2018-07-23%20上午9.22.39.png)
    
  ![Sequence模式下Focus过滤网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-092259.png)

  

  ## 截取HTTP/HTTPS数据

  ### 截取 HTTP 请求

  Charles 的主要目的是抓取捕获网络请求，这里以 iPhone 的抓包为例讲解。

  #### Charles 的设置

  要截获 iPhone 的网络请求就需要为 Charles 开启代理功能。在菜单栏选择**“Proxy” ->"Proxy Settings"**。填写代理的端口号并将**“Enable transparent HTTP proxying”**勾选上。

  ![抓取手机网络请求的电脑端设置](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-092856.png)

  

  ### iPhone 上的设置

  在电脑“系统偏好设置”中心打开网络查看本机 IP 地址，打开手机“设置”->“无线局域网”，进入当前使用的网络，点击进入当前 WIFI 的详情页（可以看到当前 WIFI 的基本信息，包括子网掩码、端口、IP地址、路由器），在最下角可以看到**“DNS”和“HTTP代理”**2个section。我们点击**“配置代理”**，设置 HTTP 代理选中“手动”。服务器处填写电脑ip地址，端口写8888。设置好后，我们打开 iPhone 上的任意需要网络请求的应用，就可以看到 Charles 弹出请求的确认菜单，单击"Allow"按钮，即可完成设置。

  ![抓取手机网络请求的手机端设置](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/11532309922_.pic.jpg)

  

  

  ### 截取 HTTPS 请求

  如果你需要捕获 HTTPS 协议的网络请求，那么则需要安装 Charles 的 CA 证书。步骤如下；

  - 首先需要在 MAC 上安装证书。点击 Charles 顶部的菜单栏，选择 **“Help” -> "SSL Proxying" -> "Install Charles Root Certificate"**。
  
    ![HTTPS抓包电脑端证书安装](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9aa40822368.png)
  
  - 在 keychain 处将新安装的证书设置为永久信任
    ![HTTPS抓包电脑端证书信任](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9aab5332151.png)

  - 即使安装了 CA 证书，Charles 默认是不捕获 HTTPS 协议的网络请求，所以我们需要对某个主机下的网络请求抓包分析的话，选中该网络请求右击选中 **“SSL Proxying Enabled”**。这样就可以看到我们感兴趣的HTTPS 网络请求了。

    ![Charles确认开启抓取HTTPS](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2018-07-23%20上午9.47.09.png)

 
   如果你需要捕获移动设备的 HTTPS 网络请求，则需要在移动设备上安装证书并作简单的设置

  - 选择 Charles 顶部菜单栏选择 **“Help” ->"Install Charles Root Certificate on a Mobile Device or Remote Browser"**。然后就可以看到 Charles 弹出的安装说明了。

    ![Charles提示手机端安装CA证书](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-101259.png)

  - 在手机设置好 Charles 代理的情况下，在手机浏览器输入 **“chls.pro/ssl”**。安装提示下载好**CA证书**。

  - 验证刚刚安装的 CA证书
    ![描述文件的验证](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9a99ea05b2e.png)  

  - iPhone 打开设置 -> 通用 -> 关于本机 -> 证书信任设置 -> 开启开关
    ![手机端CA证书的信任](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9a9ca26c907.png)
    

  - 在 Charles 菜单栏 Proxy -> SSL Proxying Setting -> 点击 Add 按钮 -> 在弹出的对对话框设置需要监听的 HTTPS 域（*:代表通配符）
    ![HTTPS抓包端口和主机设置](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9aaad2c0ff8.png)

  - 设置完毕，尽情抓取你想要的 HTTPS 网络请求吧。
    ![抓取京东HTTPS数据](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9a9a966fafe.png)
     

  

## 模拟弱网环境

  在平时开发的时候我们经常需要模拟弱网环境，并作弱网环境下的适配工作。Charles 为我们提供了这个服务。

  在 Charles 菜单栏选择 **“Proxy” -> "Throttle Settings"**。在弹出的面板上设置网络请求的参数（上行，下行带宽、利用率、可靠性等等信息）。如下图所示。
  
  ![模拟弱网环境](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2018-07-23%20上午10.27.22.png)
  

如果你想对**指定主机**进行弱网环境下的测试，可以点击上图的“Add”按钮，在弹出的面板上设置协议、主机、端口来对指定的主机进行弱网设置。
  ![设置指定网络请求的弱网模拟](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-102606.png)




## 修改网络请求


对于捕获的网络请求，我们经常需要修改网络请求的cookie、Headers、Url等信息。Charles 提供了对网络请求的编辑和重发功能。只需要选中需要修改编辑的网络请求，在对应的右上角看到有一个“钢笔”的按钮，点击后就可以对选中的网络请求进行编辑了，编辑好后可以在右下角看到 **Execute** 按钮。这样我们编辑后的网络请求就可以被执行了。

![修改网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-105440.png)




## 修改服务器返回内容

很多时候为了方便调试代码，我们会有这种需求，修改接口返回的数据节点或者内容、甚至是状态码。比如数据为空、数据异常、请求失败、多页数据的情况。 Charles 为我们提供了超实用的功能，**“Map（Map Local、Map Remote）功能”、Rewrite功能、Breakpoints功能** ，都可以实现修改服务端返回数据的功能。但是有区别和适用场景：

- Map 功能适合长期地将某一请求重定向到另一个指定的网络地址或者本地 JSON 文件
- Rewrite 功能适合对网络请求进行一些正则替换
- Breakpoints 功能适合对网络请求进行一些临时性的修改（类似于我们开发的断点作用）

### Map 功能

Map 功能分为 Map Local（将某个网络请求重定向到本地 JSON 文件） 和 Map Remote 功能（将网络请求重定向到另一个网络接口）。

在 Charles 菜单栏选择 **“Tools” -> "Map Remote" 或 “Map Local”** 即可进入相应的功能模块。



#### Map Remote 功能

适合于切换线上到本地、测试服务到正式服务的场景。比如下图从正式服务切换到测试服务

![Map Remote](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-113200@2x.png)



#### Map Local 功能

我们需要填写重定向的原地址信息和本地目标文件。我们可以先将某个接口的响应内容保存下来（选择对应的网络请求，右击点击 **Save Response** ）成为 data.json 文件。然后我们编辑里面的 status 、message、data 等信息为我们想要的目标映射文件。

![Save Response](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2018-07-23%20上午11.37.44.png)

如下所示，我将一个网络请求的内容映射到我本地的一个 JSON 文件。之后这个请求的内容都从网络变为返回我本地的数据了。

![Map Local](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-113951.png)




Map Local 可能会存在一个小缺陷，其返回的 HTTP Response Header 与正常的网络请求不一样，如果程序设置了校验 Header 信息，此时 Map Local 就会失败，解决办法是同时使用 **Rewrite功能**将相关的HTTP 头部信息 rewrite 成我们需要的信息

#### Rewrite 功能

Rewrite 适合对某个网络请求进行正则替换，以达到修改结果的目的。

假如我的 App 的界面上的显示的功能模块及其点击事件是根据接口来完成的，我想实现替换功能模块的名称的目的。步骤：点击顶部菜单栏的**“Tools” -> "Rewrite"**。在弹出的面板上勾选 **“Enable Rewrite”**。点击左下角的 **Add按钮**，在右上角的 **Name：**处写好本次配置的名称（如果有多个 Rewrite，为了后期容易区分）。

- 可以针对特定的网络请求进行 Rewrite。可以点击右上角 **Location** 面板下面的 **Add按钮**。在弹出的面板上设置网络请求配置信息。注意此时需要同时设置 Protocol、Port、Host、Path信息（我测试加了 Protocol、Host、Port这3个是无效的）

![Rewrite 针对特定网络请求的设置](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-115820.png)

- 然后对指定的 **Type** 和 **Action** 进行 Rewrite。

  Type 主要有 Add Header、Modify Header、Remove Header、Host、Path等等。

  Where 可以选择 Request 和 Response。指的是下面的修改是针对 Request 还是 Response

  ![Rewrite 设置范围](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-115855.png)

- 完成设置后点击 **Apply** 按钮，即可生效。下次继续请求该网络，返回的内容就是我们刚刚设置的内容。比如当前的“政策法规”要变成“哈哈哈，我是假的政策法规”。这时候就可以使用 Rewrite 功能

  ![Rewrite 测试结果](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-114826.png)

#### Breakpoints 功能

Breakpoints 相比于其他几个修改网络请求的特点是只是针对当前的网络请求，Breakpoints 只存在于设置过的当前的网络请求，Charles 关闭后下次打开 Breakpoints 消失了。想要修改网络请求 Breakpoints 步骤最简单，跟我们调试工具里面设置的断点一样方便。

对于我们设置了 Breakpoints 的网络请求， Charles 会在下次继续访问该请求的时候停止掉，就跟 debug 一样。此时我们可以 **Edit Request**，修改过 Request 之后点击右下角的 **Execute** 按钮。然后等到服务端返回的时候继续是断点状态，此时可以 **Edit Response**。步骤： **选中某个网络请求 -> 右击 -> 点击“Breakpoints”。**

如下图：对该接口设置了 Breakpoints。请求网络后 Edit Response，点击 execute 后服务端返回的结果就是我们编辑的内容了。

![对指定的网路请求设置断点](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-151811.png)
![在Reponse的时候修改返回的数据](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-151850.png)
![再次请求该接口返回的数据为我们设置过的](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-151906.png)



## 服务器压力测试

我们可以使用 Charles 的 **Repeat** 功能地对服务器进行并发访问进行压力测试。步骤：**选中某个网络请求 -> 右击 -> Repeat Advanced -> 在弹出的面板里面设置总共的迭代次数（Iterations）、并发数（Concurrency） -> 点击“OK” 。**开始执行可以看到以设置的并发数的规模，进行总共达设置的总共迭代次数的访问。（专业的压力测试工具：**Load Runner**）

![简单压力测试](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-135943.png)


## 反向代理

Charles 的反向代理功能允许我们将本地指定端口的请求映射到远程的另一个端口上。设置：**点击顶部菜单栏 Proxy -> 点击 Reverse Proxies**。

如下所示，我将本地的 8080 端口映射到远程的 80 端口上，点击 OK 生效后，当我继续访问本地的 80 端口，实际返回的就是远程 80 端口的提供的内容了。


![反向代理设置](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-141057.png)

## 解决与翻墙软件的冲突

Charles 的工作原理是把自己设置为系统的代理服务器，但是我们开发者经常会利用 VPN 翻墙访问谷歌查找资料（这些翻墙软件的工作原理也是把自己设置成为系统的代理服务器），为了2者和平共处。我们可以在 Charles 的 External Proxy Settings 中将翻墙的代理端口等信息填写。同时我们需要关闭翻墙软件的自动设置，更改为**“手动模式”**。（使其不主动修改系统代理）



## 总结

Charles 功能强大、界面简洁，读完这篇文章并做出练习，相信你能很快掌握它，“工欲善其事，必先利其器” ，掌握了它，相信可以为你大大提高开发中调试网络的效率。**Enjoy yourself**

## 参考链接
[唐巧的博客](http://blog.devtang.com/2015/11/14/charles-introduction/)







​	