はじめに
業務で、スマートフォンアプリ内のWebViewから開いたときだけ、表示を切り替えるWebページを修正する機会がありました。
動作確認では、PC版ChromeのDevToolsでUser-Agentを書き換えました。手順どおりに設定すると、期待していたWebView向けの表示に切り替わります。
業務中はなんとなくの理解として、PCブラウザでアプリ内webviewをみた時の再現ができるんだなあとざっくりとした認識でいました。
なぜUser-Agentを変えるとWebView向けの表示になるのか。そもそも、これでWebViewの何を再現できているのか。うまく説明できなかったため、この機会に整理してみます。
この記事では、次の3点を整理します。
- User-Agentとは何か
- Chrome DevToolsでUser-Agentを変更すると何を確認できるのか
- PCでの確認と実機確認をどう使い分けるのか
先に結論
Chrome DevToolsでUser-Agentを変更すると、WebViewと同じUser-Agentを受け取ったときのWebサイトの挙動を、PC上で手軽に確認できます。
ただし、PC版ChromeそのものがiOSやAndroidのWebViewに変わるわけではありません。
変わるのは、サーバーへ送るUser-Agentヘッダーや、JavaScriptから参照できるnavigator.userAgentの値です。描画環境やアプリとの連携まで再現されるわけではないため、最後は実際のアプリでも確認する必要があります。
User-Agentとは
User-Agentは、ブラウザなどのクライアントが、ソフトウェアや実行環境に関する情報をサーバーへ伝えるHTTPリクエストヘッダーです。
HTTPリクエストでは、次のような形で送信されます。
GET /example HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 ...
ざっくり言えば、アクセスしてきたクライアントの「名札」のようなものです。
ただし、本人確認に使える身分証明書ではありません。内容は利用者側で書き換えられます。今回使ったChrome DevToolsも、User-Agentを書き換える方法の一つです。
Webページ上のJavaScriptからは、次のようにUser-Agent文字列を確認できます。
console.log(navigator.userAgent);
Webサイト側では、HTTPヘッダーをサーバー側で確認したり、navigator.userAgentをJavaScriptから確認したりして、表示や処理を切り替えることがあります。
WebViewではどのように使われるのか
WebViewは、スマートフォンアプリの中にWebページを表示するための仕組みです。
アプリによっては、WebViewのUser-Agentにアプリ固有の文字列を追加しています。Webサイト側は、その文字列を見て「アプリ内からのアクセスかどうか」を判定できます。
以下はイメージです。
const isAppWebView = navigator.userAgent.includes("ExampleApp");
if (isAppWebView) {
// アプリ内WebView向けの表示や処理
}
たとえば、アプリ内では不要なナビゲーションを隠したり、WebView専用の案内を表示したりできます。
iOSのWKWebViewには、アプリ側からUser-Agentを指定するcustomUserAgentがあります。AndroidのWebViewにも、setUserAgentString()でUser-Agentを設定する仕組みがあります。
- Apple Developer Documentation:WKWebView.customUserAgent
- Android Developers:Build web apps in WebView
Chrome DevToolsでWebView向けの表示を確認する
Chrome DevToolsでは、Chromeが送信するUser-Agentを一時的に変更できます。
大まかな手順は次のとおりです。
- Chromeで確認したいページを開く
- DevToolsを開く
- DevTools右上のメニューから「More tools」→「Network conditions」を開く
- 「User agent」の自動選択を解除する
- 使用したいUser-Agentを選択するか、任意の文字列を入力する
- ページを再読み込みする
これで、指定したUser-Agentを受け取ったときのWebサイトの挙動を確認できます。
検証が終わったら、自動選択へ戻しておくと安心です。設定を残したままにすると、その後に開いたページも変更したUser-Agentで確認することになります。
DevToolsの表示や項目名は、Chromeのバージョンによって変わる可能性があります。詳しい手順は、Chrome DevToolsの公式ドキュメントを確認してください。
なお、User-Agentの変更と、DevToolsのDevice Modeによる画面サイズやタッチ操作のエミュレーションは別の機能です。User-Agentを変えただけでは、画面の幅や操作方法まではスマートフォン向けになりません。
確認できること・できないこと
User-Agentの変更は、User-Agentを条件に表示や処理を分けているWebサイトの確認に向いています。
たとえば、次のような場面です。
- アプリ内WebViewでだけ表示・非表示を切り替える要素の確認
- 特定のブラウザ向けに表示する案内の確認
- User-Agentによってサーバーが返すHTMLを変えている処理の確認
-
navigator.userAgentを使ったJavaScriptの分岐の確認 - 実機確認の前に、PC上で素早く修正内容を確認したいとき
今回の業務でも、実機を開く前にWeb側の表示分岐を確認できたため、修正中の動作確認には便利でした。
一方、User-Agentを変えても、PC版Chromeの内部的な動作は変わりません。Chromeの公式ドキュメントでも、User-Agentの変更はChrome内部の動作を変えるものではなく、配信されるコンテンツが変わるものだと説明されています。
確認できる範囲を整理すると、次のようになります。
| 確認したいこと | User-Agentの変更 |
|---|---|
| User-Agentによる要素の表示・非表示 | 確認しやすい |
| アプリ固有文字列を使った判定 | 確認しやすい |
| User-Agentによるサーバー側の分岐 | 確認しやすい |
| 実際のWebViewでのレイアウトや操作感 | 十分ではない |
| アプリとWebページの連携 | 基本的に再現できない |
| OS・実機固有の挙動 | 再現できない |
実際のWebViewとは、ほかにも次のような違いがあります。
- WebViewとChromeのバージョンや描画環境
- Cookieやログイン状態
- Local Storageなどに保存されたデータ
- アプリから付与される独自ヘッダー
- アプリとWebViewをつなぐ処理
- カメラや位置情報などの権限
- WebView独自の設定
そのため、PC版Chromeで期待どおりになったからといって、実際のアプリでも同じように動くとは限りません。
PCでの確認は、User-Agentによる分岐を素早く確かめるためのもの。実機確認は、WebViewを含めたアプリ全体の動作を確かめるためのもの。このように役割を分けて考えると分かりやすくなりました。
User-Agentだけに頼りすぎない
User-Agentは書き換えられるため、認証やアクセス制御の根拠には向いていません。また、文字列の形式は複雑で、ブラウザの更新などによって判定が期待どおりに動かなくなる可能性があります。
目的によっては、別の方法が適しています。
- 画面幅に応じて表示を変える:レスポンシブデザイン
- 特定の機能が使えるか判断する:Feature Detection
- ユーザーを認証・認可する:Cookieやトークンなど、認証用の仕組み
- アプリとWebページを連携する:アプリ専用のインターフェース
User-Agentによる判定がすべて悪いわけではありません。大切なのは、「何を判定するために使うのか」を分けて考えることだと思います。
まとめ
今回、Chrome DevToolsでUser-Agentを変更したことで、アプリ内WebView向けの表示分岐をPC上で効率よく確認できました。
一方で、変更しているのはChromeが送信するUser-Agentヘッダーや、JavaScriptから参照できるnavigator.userAgentの値です。WebViewそのものを再現しているわけではありません。
実際に使ってみて、次のように考えると分かりやすいと感じました。
Chrome DevToolsによるUser-Agentの変更は、別の環境へ変身する機能ではありません。
サーバーへ送るUser-Agentヘッダーや、JavaScriptから参照できるnavigator.userAgentの値を書き換え、別の環境として名乗ったときのWebサイトの反応を確認する機能である。
User-Agentに依存する処理の確認には便利ですが、それだけで実機確認を置き換えることはできません。
PC上での効率的な確認と、実際のWebViewでの確認。それぞれの役割を理解して使い分けていきたいと思います。