簡書上的文章已經(jīng)不再維護(hù),有興趣閱讀其他文章,或一起交流的朋友,請移步 我的博客:punmy.cn
原文
本篇博客中所使用的環(huán)境為:macOS Sierra 10.12,Charles 4.0.1,iPod Touch 5。

在 iOS 開發(fā)中,我們常常要涉及到網(wǎng)絡(luò)編程,而網(wǎng)絡(luò)編程中的調(diào)試往往令人頭痛。此外,我們也有時也會需要抓取一些 App 的網(wǎng)絡(luò)包,以便了解它網(wǎng)絡(luò)請求的API。本篇要介紹的 Charles 就是一款非常好用的網(wǎng)絡(luò)調(diào)試工具,它可以輕松地滿足我們的上述需求。
準(zhǔn)備工作
啟動 Charles
Charles 的下載安裝這里就不再贅述。啟動 Charles 后,我們可以看到 Charles 的主界面。

窗口的左側(cè)是抓取到的網(wǎng)絡(luò)包,通常 Charles 啟動后我們就可以看到 Mac 上的一些網(wǎng)絡(luò)包開始出現(xiàn)在這里。
窗口右側(cè)是選中的網(wǎng)絡(luò)包的詳細(xì)信息,如 URL、狀態(tài)碼等。
窗口上方是一些常用的工具。鼠標(biāo)經(jīng)過時就會有相應(yīng)的提示,后面再細(xì)說。
右下角是 Charles 當(dāng)前的狀態(tài)。可以顯示 Recording、BreakPoints、Rewrite 等功能是否啟用。
連接設(shè)備
要抓取 iOS 設(shè)備上的網(wǎng)絡(luò)包,首先要將 iOS 設(shè)備和裝有 Charles 的電腦連接到同一個局域網(wǎng)下,并將 Charles 設(shè)置為 iOS 的 HTTP 代理,這樣 Charles 就可以捕捉到所有進(jìn)出 iOS 的網(wǎng)絡(luò)包。設(shè)置的步驟如下:
- 確保裝有 Charles 的 mac 和等待調(diào)試的 iOS 設(shè)備在同一局域網(wǎng)內(nèi);
- 查找 mac 的 IP 地址(可以在 Charles 菜單欄的 Help -> Local IP Address 直接查看);

- 在 iOS 設(shè)備上的 設(shè)置 -> Wi-Fi 中,點(diǎn)擊已連接 WiFi 右側(cè)的 詳細(xì)按鈕(藍(lán)色),將 WiFi 詳情頁底部的 HTTP 代理 設(shè)為手動,并在 服務(wù)器 一欄填入上一步中 mac 的 IP 地址,在 端口 一欄填入 Charles 的默認(rèn)代理端口 8888,然后退出設(shè)置;

- 此時如果網(wǎng)絡(luò)正常的話,Charles 會提示有設(shè)備企圖連接,同意連接,便完成了代理的設(shè)置。

注意:許多公司的內(nèi)部局域網(wǎng)會限制設(shè)備間的互相訪問,這可能會導(dǎo)致 Charles 抓取不到網(wǎng)絡(luò)包,這種情況下可以嘗試自己創(chuàng)建一個熱點(diǎn)。
連接完成后,窗口左側(cè)開始出現(xiàn) Charles 抓到的包,說明進(jìn)展順利。
抓包
捕獲
Charles 啟動后,就處于 Recording 狀態(tài),會自動捕捉網(wǎng)絡(luò)包,點(diǎn)擊窗口上方工具欄的第二個按鈕可以停止捕捉。
在窗口左側(cè)的選擇上方的 Structure 或 Sequence 可以切換網(wǎng)絡(luò)包的顯示方式。
- Structure 是根據(jù)主機(jī)名以樹狀顯示,便于查看同一主機(jī)名的網(wǎng)絡(luò)包,每當(dāng)有新的請求到達(dá)時,相應(yīng)的主機(jī)名就會用黃色高亮閃爍。我們通常都是采用這個方式。
- Sequence 則是根據(jù)網(wǎng)絡(luò)請求的時間順序依次顯示,在這個模式下,整個窗口的布局也會有所變化。
選中某個網(wǎng)絡(luò)包后,右側(cè)就會顯示該網(wǎng)絡(luò)包的詳細(xì)信息。

開始抓包之后,我們會發(fā)現(xiàn),只有 HTTP 的包被成功解析了,HTTPS 的包都處于加密狀態(tài)。要想查看 HTTPS 的包內(nèi)容,可以查看本文中 SSL 代理的小節(jié)。
過濾
開始抓包后,隨著時間的推移,抓取到的網(wǎng)絡(luò)包越來越多,這是我們可以使用過濾功能,來過濾出我們想要的網(wǎng)絡(luò)請求。
在 Proxy -> Recording Settings 中可以設(shè)置網(wǎng)絡(luò)包的過濾選項(xiàng)。

過濾選項(xiàng)中有 Include 和 Exclude 兩種選項(xiàng)。只有當(dāng) Include 為空時,Exclude 中的設(shè)置才會生效。過濾條件支持通配符。
修改網(wǎng)絡(luò)包
修改歷史請求
可以將歷史的請求修改后,再次發(fā)送。
只需選中某個請求,點(diǎn)擊上方工具欄中的藍(lán)色鋼筆按鈕(第四個),就可以進(jìn)行修改。完成修改后,點(diǎn)擊下方的 Execute 執(zhí)行請求。

斷點(diǎn)
窗口上方的工具欄中,第四個按鈕就是 Enable BreakPoints,用來啟用或禁用斷點(diǎn)。也可以在 Proxy -> BreakPoints Setting 中設(shè)置更多具體內(nèi)容。
在 Charles 中可以像調(diào)試程序一樣添加斷點(diǎn)。方法是右鍵點(diǎn)擊左側(cè)窗口的某個請求,選擇 BreakPoints 添加斷點(diǎn)。這樣當(dāng)這個請求發(fā)出或者收到 response 的時候,就會先被 Charles 攔截下來,并觸發(fā)斷點(diǎn)。

觸發(fā)斷點(diǎn)后,可以對斷點(diǎn)的網(wǎng)絡(luò)包進(jìn)行各種編輯,然后再繼續(xù)。點(diǎn)擊 Execute 就可以繼續(xù)。
同時,也可以在 Proxy -> BreakPoints Setting 設(shè)置斷點(diǎn)的各種規(guī)則。例如,是在 request 的時候觸發(fā)還是 response 的時候。

由于設(shè)置斷點(diǎn)時,Charles 是先攔截下整個網(wǎng)絡(luò)包,再觸發(fā)斷點(diǎn),當(dāng)網(wǎng)絡(luò)包比較大的時候,常常會導(dǎo)致應(yīng)用超時,觸發(fā)網(wǎng)絡(luò)錯誤的警告,因此,自動地根據(jù)規(guī)則修改網(wǎng)絡(luò)包有時顯得尤為重要。這就是下面要說的篡改。
篡改(Rewrite)
Rewrite 是按照一組事先設(shè)置的規(guī)則,篡改特定的網(wǎng)絡(luò)包中的數(shù)據(jù)。
在 Tools -> Rewrite 中,選中 Enable Rewrite 來開啟 Rewrite。

勾選 Debug in Error Log 選項(xiàng),就能在 Charles 控制臺中看到 Rewrite 的記錄。
首先要在右側(cè)的規(guī)則列表中添加一個新規(guī)則。在新規(guī)則中添加要 Rewrite 的 Location,然后再下方添加具體的篡改規(guī)則。規(guī)則中可以使用通配符。

這樣稍后匹配條件的網(wǎng)絡(luò)包到達(dá)的時候,Charles 就會自動將其中的內(nèi)容按規(guī)則篡改。
映射
Charles提供的映射功能可以將本地文件或者遠(yuǎn)程的服務(wù)器作為某個請求的 Response??梢苑奖愕剡M(jìn)行一些特殊的測試。
1、Map Local
本地映射,在 Tools -> Map Local。可以選擇一個本地文件作為某個請求的 Response,并且 Charles 會幫你封裝好 Response。

2、Remote Remote
遠(yuǎn)程映射和本地映射的功能類似,只是將數(shù)據(jù)源換成了遠(yuǎn)程服務(wù)器。相當(dāng)于將請求交給另一個服務(wù)器處理
網(wǎng)絡(luò)環(huán)境模擬
Charles 還可以模擬不同網(wǎng)速環(huán)境,可以很方便地測試應(yīng)用在網(wǎng)絡(luò)差的情況下的 bug。
在 Proxy -> Throttle Settings 中勾選 Enable Throttling,或者直接點(diǎn)擊窗口上方的工具欄中的烏龜??按鈕就可以啟用,這個按鈕十分形象。
在 Proxy -> Throttle Settings 中,添加要針對的 Locations,如果選中了 Only for selected hosts,并且Locations中有數(shù)據(jù),則只有 Locations 列表中的請求會被限速,否則會對全局限速。在 Throttle Configuration 中可以對網(wǎng)絡(luò)環(huán)境進(jìn)行十分詳細(xì)的配置,包括網(wǎng)絡(luò)的穩(wěn)定程度、網(wǎng)速、環(huán)境等。

SSL 代理
在使用 Charles 的過程中,我們會發(fā)現(xiàn),只有未加密的 Http 請求才能被 Charles 正確的解析出數(shù)據(jù),其余的 Https 請求都處于加鎖的狀態(tài),但我們不可避免的需要抓取 Https 的包。SSL 代理就可以完美解決這個問題。
要啟用 SSL 代理,先要在 Proxy -> SSL Proxying Settings 中勾選 Enable SSL Proxying,然后配置要代理的 Location,一般可以直接填星號,以匹配所有請求。

接下來還要安裝 Charles 的證書。
Charles 中的 HTTPS 代理的原理是,Charles 充當(dāng)一個中間人,針對目標(biāo)服務(wù)器動態(tài)地生成一個使用 Charles 根證書(Charles CA Certificate)簽名的證書;請求發(fā)生的時候, Charles 會接收 web 服務(wù)器的證書,而把自己生成的證書給客戶端看。
因此在在使用 Charles 作為 HTTPS 代理時,客戶端在請求 HTTPS 接口的時候會彈出安全警告,提示 Charles 根證書不被信任。我們需要添加 Charles 根證書為信任證書中。
方法如下:
1、點(diǎn)擊 Help -> SSL Proxying,根據(jù)被抓包設(shè)備的類型,來選擇對應(yīng)的安裝選項(xiàng)(如果是 OSX 就直接選擇 Install Charles Root Certificate);
2、如果是iOS真機(jī),則會彈出下面的提示,此時不用按上面的提示來配置代理,只要按照上文的步驟配置過代理了就可以了。然后在 Safari 中打開 chls.pro/ssl 安裝 Charles 的證書,就 OK 了。

設(shè)置好 SSL 代理后,HTTPS 請求就統(tǒng)統(tǒng)解鎖啦!

-
注意:iOS9以上系統(tǒng)要使用 Charles 作為 SSL 代理的話要關(guān)閉 APP Transport Security ,關(guān)閉方法為在APP的info.plist文件添加以下key:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
Charles 是一個強(qiáng)大的抓包調(diào)試工具,它的功能遠(yuǎn)不止這些,但本篇作為一篇入門的博客,就先介紹這么多啦,更多功能等待大家探索~
套餐
Postman
Postman 是一個測試 API 的利器。

Charles 搭配 Postman 更好用噢~
Postman 是 Chrome 瀏覽器中的一個小應(yīng)用,可以在 Chrome 應(yīng)用商城中找到。是居家旅行測試 Web API 的好幫手!