HTTPリクエストにCharlesでブレークポイントを貼ってみる

# はじめに

[Charles](http://www.charlesproxy.com/)というデバッグプロキシを使うとHTTPリクエストやレスポンスにブレークポイントを設定して手軽に書き換えたりできて非常に便利。
とうことでCharlesのブレークポイントの具体的な使い方について。

Charlesの概要、セットアップ、基本知識とかはこちら。
* [俺的フロントエンドエンジニア三種の神器に認定したCharlesについて 〜その1〜 Charlesの素敵なところ](http://qiita.com/dayoshix/items/b658389eea076b2e8ec3)
* [俺的フロントエンドエンジニア三種の神器に認定したCharlesについて 〜その2〜 インストールと設定](http://qiita.com/dayoshix/items/d02e46b033b8f7d9f471)
* [俺的フロントエンドエンジニア三種の神器に認定したCharlesについて 〜その3〜 最初に覚えたい基本的なこと](http://qiita.com/dayoshix/items/9bfce504686108545757)

# やること
ブレークポイントの手順を説明するためにYahoo!Japanのindex.htmlへのGETリクエストにブレークポイントを設定し、レスポンスとなるHTML内のロゴ画像のsrcをQiitaのKobitoの画像のURLに書き換えてKobitoっぽいサイトにする。

# 手順
1. **セッションの記録を開始する**
ツールバーから`Recording`ボタンを押し込んだ状態にする。
![01-start-recording.png](https://qiita-image-store.s3.amazonaws.com/0/31639/90c305f6-d10e-34f4-1086-97dca3be4af4.png)

1. **WebブラウザでHTTPリクエストを発生させる**
セッションにこんな感じのHTTPリクエストが記録される。
![02-httpリクエスト.png](https://qiita-image-store.s3.amazonaws.com/0/31639/4ac6a89c-17a4-f380-1f80-160034097c0b.png)

1. **セッションの記録を停止する**
余計な情報を記録しないようにセッションの記録と停止は都度行ったほうが捗る。
ツールバーから再度`Recording`ボタンを押して停止状態にする。

1. **index.htmlのGETリクエストを探す。**
これや！！
![03.png](https://qiita-image-store.s3.amazonaws.com/0/31639/246baaf6-57e7-3d4b-b112-1b15cdd480f0.png)

1. **ブレークポイントを設定する**
選択したリクエストを右クリックするとコンテキストメニューが表示されれるので`Breakpoints`を選択する。
![04.png](https://qiita-image-store.s3.amazonaws.com/0/31639/4d6f06a5-5dc1-52d9-efef-a7c9cc78261e.png)
選択するとメニューが閉じるだけなので拍子抜けするがブレークポイントはちゃんと設定されている。
もう一度右クリックして確認してみる。
![05.png](https://qiita-image-store.s3.amazonaws.com/0/31639/04b944f3-54b4-c54d-ca8b-e92ae1f40753.png)
`Breakpoints`にチェックがついている。

1. **ブレークポイントのターゲットをレスポンスのみに設定する**
現状のままでもブレークポイントは設定されているが、デフォルトの動きとしてリクエストとレスポンス両方に設定される。
今回はレスポンスがターゲットなのでリクエストのブレークポイントを解除してみる。
アプリケーションメニューから`Proxy`-`Breakpoints..`を選択する。
![06.png](https://qiita-image-store.s3.amazonaws.com/0/31639/331510b4-746d-a974-4fb1-0a283f51560a.png)
下記ダイアログが表示され、先程設定したブレークポイントが設定されていることが確認できる。
![07.png](https://qiita-image-store.s3.amazonaws.com/0/31639/4228b2dd-c002-8083-8de2-488ba91ed81b.png)
ターゲットのブレークポイントをダブルクリックするとブレークポイントの詳細情報ダイアログが表示される。
`Request`、`Responce`にチェックが付いている`Request`を外して`OK`で画面を閉じる。
![08.png](https://qiita-image-store.s3.amazonaws.com/0/31639/6f41a645-7e31-1b8f-4e63-f577a2728848.png)

1. **Webブラウザをリロードする**
Webブラウザをリロードして再度同じHTTPリクエストを発生させてみる。
Charlesの画面が下記のようにブレークポイント画面に切り替わる。
![10.png](https://qiita-image-store.s3.amazonaws.com/0/31639/5907e506-0a81-3edf-a391-9bc11f26286d.png)
Webブラウザも読み込み中になっているはず。
つまりレスポンスがWebブラウザに到達せずCharlesで止まった状態。
`Execute`でレスポンスを流し、`Abort`でエラーレスポンスを返す。

1. **レスポンスの中を見る**
`Edit Response`を押すと編集ビューが表示される。
ここではHTTPレスポンスのヘッダーやボディを書き換えることができる。
ここではHTML内のロゴ画像をQiitaのKobito画像に書き換えてみる。
`HTML`を押してレスポンスボディの中のロゴ画像の要素を特定する。
![11.png](https://qiita-image-store.s3.amazonaws.com/0/31639/76a1b1ec-a258-7cd9-3ef9-7940404b58a6.png)

1. **レスポンスを書き換える**
こんな感じにKobito画像のURLに書き換えてみた。
![12.png](https://qiita-image-store.s3.amazonaws.com/0/31639/8e06af5e-9704-0442-2312-2ce09520a135.png)

1. **書き換えたレスポンスをWebブラウザに流す**
`Execute`ボタンを押して流す。

1. **結果を確認**
Webブラウザを見てみるとYahooのロゴがKobitoに書き換わっている。
こんな感じで。
![13.png](https://qiita-image-store.s3.amazonaws.com/0/31639/8c34de61-c0be-caf9-ae60-9bae2aec4d59.png)

# HTTPリクエスト

リクエストにもレスポンスと同様の操作でブレークポイントを設定してヘッダーやURLを書き換えることが出来る。
フロントエンジニア的にいまいち使いどころを思いつかなかったので詳しい説明はスキップした。
サーバーサイド的には想定外のリクエストを発生させておかしな動きをしないかチェックするのに役立つかも。

# 使いどころ

レスポンスをインスタントに書き換えたい場合に良いかも。
本番環境のJavascriptやcssのレスポンスにブレークポイントを設定し、レスポンスボディを開発中のソースコードで上書きして本番環境ベースで動作確認したりとかに使ったする。

# FAQ

## **Q1. 目的のリソースがブラウザキャッシュされてリクエスト自体発生しないのでブレークポイントが設定できないよ！！**
ブラウザのキャッシュをクリアする。
ついでにChales上で対象のリクエストを選択し、右クリックメニューから`No Caching`を選択すると選択したリクエストがブラウザキャッシュされなくなるので便利。
![14.png](https://qiita-image-store.s3.amazonaws.com/0/31639/7339f929-0b22-c493-2bd3-d30207d80a52.png)
使い終わったら解除することをお忘れなく。

## **Q2. iOSネイティヴアプリのWebView上で上記と同じ問題が。。**
ネイティヴアプリのブラウザキャッシュをクリアする場合はアプリを再インストールすればよいが非常に面倒だし毎回やってられない。
キャッシュされたリソースをロードするHTML自体はキャッシュされないので、HTML内のリソースのURLをChalresのブレークポイントを使って書き換えてキャッシュを防ぐ。

例えば、HTMLレスポンスにブレークポイントを設定して、キャッシュされたリソースのURLに適当なクエリパラメータを設定する。

  * 変更前

```html

<script src="http://hogehoge.org/scripts/main.js"></script>

```

  * 変更後

```html

<script src="http://hogehoge.org/scripts/main.js?abc"></script>

```

サーバーサイドのバリデーションが厳し目だと変なクエリパラメータ付加するとそれだけでエラーが発生したりして難儀したが、その場合は`?`だけURLの末尾に追記するとうまくいったような気がする。

```html

<script src="http://hogehoge.org/scripts/main.js?"></script>

```

# 最後に

次回はここらへんに関して書いてみる。
* レスポンスをローカルファイルに置き換える 〜 Map Local 〜
* リクエストを異なるリモートホストに向ける 〜 Map Remote 〜