Chrome 113 で、 DevTools の Network ペインで HTTP ヘッダを好きなように編集して、いろんな状態をお試しできるようになっている。 What's New in DevTools (Chrome 113) - Chrome Developers で紹介されている。
GitHub から example.com を fetch してみる
試しに、 CSP で外部への通信がそれなりに制限されている GitHub から、 example.com への fetch を成功させてみる (外部サイトへの通信は、認証情報や秘密の情報の漏洩などに気をつけて試してください。この記事の事例は多分安全と思って書いています)。 Chrome のバージョンは 113.0.5672.92(Official Build) (arm64)
。
GitHub の CSP ヘッダを上書き
https://github.com/git/git を開き*1、まず素朴に DevTools の Console から fetch する ( fetch('https://example.com/')
)と失敗。 CSP のルールで弾かれている。
Network ペインで編集したい通信 (今回は https://github.com/git/git
) をクリックして Headers を開き、 Response Headers のどれでもよいのでホバーして鉛筆マークを押せば、編集モードに入ろうとする。
ここで、「Select a folder to store override files in.」と言われて、「Select folder」を押すとファイルエクスプローラが開く。今回は適当にデスクトップにフォルダをつくった。
すると「デベロッパーツールでは 〜(選んだパス) へのフルアクセスがリクエストされます。機密情報の漏えいにご注意ください。」と案内されて、許可と拒否を選べる。ミスって秘密のファイルが入ったフォルダなどを選んでもやり直せるようになっていて丁寧。今回は新しくつくったフォルダなので許可する。
これでようやく編集モードに入る。わかりづらいけど、等幅フォントになり、ホバーすると textarea の枠が薄く表示されて、編集できそうな感じになる。 Content-Security-Policy ヘッダの 2〜3行目にある connect-src
に example.com
を追加した (CSP: connect-src - HTTP | MDN を許可すると fetch できるようになる)。編集したヘッダはわかりやすく緑になっている。
右上の Header Overrides をクリックすると、 Sources ペインの Overrides タブで .headers ファイルが開かれ、編集したヘッダの一覧が見られる。 GitHub の CSP ヘッダの内容が長くて見づらいけど、パス github.com/git の git というファイル (つまり github.com/git/git) への通信の際に、 CSP ヘッダが上書きされるよ、というのがわかる。ちなみにここでもヘッダの値を編集できる。
これだけでは、まだ今のページには反映されていないので、 fetch すると失敗する。適用するには再読み込みが必要。
再読み込みすると、 github.com/git/git への通信の Status の 200 の左にマークがついていて、 Header Overrides が適用されていることがわかる。
Headers を見ると、さっき編集された状態のままになっている (画面を大きくしてしまって行がずれてるけど、 1行目の最後のほうに example.com が入っている)。
これでいけるかと思って fetch すると、こんどは CORS で失敗する。 example.com 側で、 github.com からのアクセスを許可していない。
example.com の CORS のヘッダを上書き
つまり example.com のヘッダも書き換えたらよい。今度は編集モードに入った後に登場する「Add header」ボタンで Access-Control-Allow-Origin - HTTP | MDN ヘッダ (値は https://github.com
) を追加する。
Sources ペインで見ても、 example.com の index.html に対してヘッダが増えている。
この場合は、現在見ているページではなくて fetch してくるページなので、再読み込みとかはなく、新しく fetch し直したら成功する。めでたく HTML が console.log された。
fetch('https://example.com/').then(res => res.text()).then(t => console.log(t))
途中で指定したフォルダの中身は何?
ヘッダの編集モードに入るときにフォルダを指定した。 Sources ペインで雰囲気はわかるかもしれないが、パスごとのフォルダができ、その中の .headers ファイルに JSON で上書きヘッダが書かれている。
$ tree -a ~/Desktop/chrome-http-header-override/ /Users/hogashi/Desktop/chrome-http-header-override/ ├── example.com │ └── .headers └── github.com └── git └── .headers 4 directories, 2 files
$ cat ~/Desktop/chrome-http-header-override/example.com/.headers [ { "applyTo": "index.html", "headers": [ { "name": "access-control-allow-origin", "value": "https://github.com" } ] } ]
このファイルを直接編集しても反映される。試しに example.com の .headers ファイルで、 hoge ヘッダを書き込んでみた。
$ cat ~/Desktop/chrome-http-header-override/example.com/.headers [ { "applyTo": "index.html", "headers": [ { "name": "access-control-allow-origin", "value": "https://github.com" }, { "name": "hoge", "value": "hogashi" } ] } ]
fetch すると Hoge ヘッダがちゃんとついている。自然とcamelcase にされるのですね。
上書きをやめるには?
内容を残したまま一旦オフにしたいときは、「Enable Local Overrides」のチェックを外せばよさそう。
あるいは、 .headers ファイルを消せば、上書きされなくなる。全部吹き飛ばすには、「Clear configuration」を押せばよい。
感想
機能は便利そう。気をつけるポイントはありつつ、今までサーバ側を変更しないといけなかった部分をクライアントのみで試行錯誤できるので、開発しやすさがあがっていきそう。
権限を要求してまでローカルのファイルに保存する仕組みにした理由はちょっと気になる。直接エディタなどで編集できるのは便利なので、そこを優先したのかな……? とか考えているけどわからない。
*1:一応シークレットウィンドウで開いた