- ●ユーザーエージェントとは?
- ●JavaScriptでユーザーエージェントを取得する10の方法
- ●ユーザーエージェント廃止の動きと今後の対応
- ●ユーザーエージェント判定の注意点
- まとめ
●ユーザーエージェントとは?
皆さんは、ユーザーエージェントという言葉を聞いたことがあるでしょうか。
ユーザーエージェントとは、ブラウザやデバイスの情報を含む文字列のことを指します。
私たちがWebサイトを訪れる際、使用しているブラウザやデバイスの情報が、このユーザーエージェントという形でサーバーに送信されているのです。
○ユーザーエージェントの役割
では、このユーザーエージェントは一体何のために使われているのでしょうか。
実は、ユーザーエージェントの主な役割は、Webサイトがブラウザ判定やデバイス判定を行うための情報を提供することにあります。
例えば、あるWebサイトがモバイル端末用に最適化されたレイアウトを提供したいとします。
そんな時、ユーザーエージェントを使ってアクセス元のデバイスがスマートフォンなのかタブレットなのかを判定し、それぞれに合わせた表示を行うことができるのです。
また、ブラウザごとに異なる機能や挙動に対応するために、ユーザーエージェントを使ってブラウザ判定を行うこともよくあります。
ChromeとSafariでは対応しているWebの機能が異なることがありますよね。
そんな時、ユーザーエージェントを見れば、アクセス元のブラウザがChromeなのかSafariなのかを判別できます。
○ユーザーエージェント文字列の例
ユーザーエージェント文字列の具体例を見てみましょう。
Chromeのユーザーエージェントはこのような感じです。
一方、iPhoneのSafariではこんな感じ。
ユーザーエージェント文字列を見ると、OSやブラウザ、デバイスの種類などの情報が含まれていることがわかりますね。
Webサイトはこの情報をもとに、アクセス元に合わせた最適なコンテンツを提供しているわけです。
●JavaScriptでユーザーエージェントを取得する10の方法
さて、JavaScriptでユーザーエージェントを取得する方法ですが、実はいくつかのアプローチがあります。
皆さんも経験上、ブラウザ判定やデバイス判定で頭を悩ませたことがあるのではないでしょうか。
そんな時、適切な方法でユーザーエージェントを取得できれば、問題解決に近づくはずです。
ここからは、JavaScriptでユーザーエージェントを取得する代表的な10の方法を、サンプルコードを交えて詳しく解説していきます。
初心者の方にもわかりやすいよう、丁寧に説明していきますので、ぜひ実際にコードを試しながら読み進めていってください。
○navigator.userAgentプロパティを使う
まずは、もっともポピュラーな方法である「navigator.userAgent」プロパティの使い方から見ていきましょう。
navigator.userAgentは、現在のブラウザのユーザーエージェント文字列を返してくれるプロパティです。
□サンプルコード1:navigator.userAgentの基本的な使い方
実行結果
このように、navigator.userAgentを使えば、簡単にユーザーエージェント文字列を取得できます。
取得したユーザーエージェント文字列を解析することで、ブラウザ名やバージョン、OSなどの情報を抽出できるわけですね。
ただ、ユーザーエージェント文字列のフォーマットはブラウザごとに異なるため、解析は少しややこしいかもしれません。
そんな時は、後述するようなライブラリやAPIを使うのも手です。
○ウィンドウオブジェクトのclientInformationプロパティを使う
navigator.userAgentと同じように、ウィンドウオブジェクトのclientInformationプロパティからもユーザーエージェント情報を取得できます。
実は、navigator.userAgentとwindow.clientInformation.userAgentは同じ値を返すのです。
□サンプルコード2:clientInformationプロパティの使用例
実行結果
navigator.userAgentと同じ結果が得られましたね。
おさらいですが、この2つは同じ情報を返してくれるので、どちらを使ってもOKです。
○正規表現を使ってユーザーエージェント文字列を解析する
さて、navigator.userAgentやclientInformationで取得したユーザーエージェント文字列ですが、そのままでは使いづらいですよね。
ブラウザ名やバージョン、OSといった情報を個別に取り出したいところです。
そこで登場するのが、正規表現を使ったユーザーエージェント文字列の解析です。
正規表現を使えば、ユーザーエージェント文字列からブラウザ名などの特定の情報を抽出できます。
□サンプルコード3:正規表現によるユーザーエージェント解析
実行結果(例)
このサンプルコードでは、ユーザーエージェント文字列に対して正規表現を使った検索を行っています。
ブラウザ名の判定には /(chrome|firefox|safari|opera|trident)/i
という正規表現を使用しています。
この正規表現は、ユーザーエージェント文字列内のブラウザ名を表す部分にマッチします。
同様に、ブラウザバージョンの判定には /version\/(\d+(\.\d+)?)/i
、OSの判定には /(windows|mac|linux|android|ios)/i
という正規表現を使用しています。
正規表現での検索結果は、match()メソッドによって配列で返されます。
その配列の要素を取り出すことで、目的の情報を抽出できるわけですね。
ただ、正規表現の構成は少しややこしいですし、ブラウザごとに異なるユーザーエージェント文字列のフォーマットに合わせて正規表現を作るのは大変です。
そこで、次に紹介するようなライブラリを使うのもおすすめです。
○JSライブラリのUA-parserを使う
正規表現でユーザーエージェント文字列を解析するのは手間がかかります。
そこで、ユーザーエージェント解析用のJavaScriptライブラリを使う方法もあります。
代表的なライブラリの1つが「UA-parser」です。
UA-parserを使えば、ユーザーエージェント文字列から簡単にブラウザ名やバージョン、OSなどの情報を取得できます。
□サンプルコード4:UA-parserライブラリの使用例
実行結果(例)
UA-parserを使う場合、まずHTMLにライブラリのスクリプトを読み込みます。
そして、UAParserオブジェクトを生成し、getResult()メソッドを呼び出すだけで解析結果が得られます。
解析結果は連想配列の形で返されるので、result.browser.nameでブラウザ名、result.browser.versionでバージョン、result.os.nameでOSといった具合に、必要な情報をドット記法で取り出せます。
正規表現を自分で書くよりも簡単で便利ですし、ブラウザごとの違いも吸収してくれるので、ユーザーエージェント解析にはUA-parserのようなライブラリを使うのがお勧めです。
○ライブラリのua-device-detectorを使う
UA-parserの他にも、ユーザーエージェント解析用のライブラリはいくつかあります。
その中でも注目したいのが「ua-device-detector」です。
ua-device-detectorは、ユーザーエージェント文字列からデバイスの種類(スマートフォン、タブレット、PCなど)を判定することに特化したライブラリです。
レスポンシブWebデザインを採用していて、デバイスごとに最適化されたUIを提供したい場合に役立ちます。
□サンプルコード5:ua-device-detectorの基本的な使い方
実行結果(例:iPhoneでアクセスした場合)
ua-device-detectorの使い方は、UA-parserとよく似ています。
まずライブラリを読み込んだ上で、UADeviceDetectorオブジェクトを生成します。
そして、detectorオブジェクトのdeviceプロパティから、デバイスの種類やブランド、モデルといった情報を取得できます。
特にデバイスの種類(device.type)は、’smartphone’、’tablet’、’desktop’といった文字列で返されるので、UIの出し分けに使いやすいですね。
ただ、こうしたデバイス判定はユーザーエージェント文字列に強く依存しているため、ユーザーエージェントの偽装などには注意が必要です。
できるだけ、ユーザーエージェントに頼りすぎない設計を心がけましょう。
○User-Agent Client Hintsを使う
ここまで紹介してきた方法は、いずれもユーザーエージェント文字列を使った判定方法でした。
しかし、GoogleのChromeチームは、プライバシー保護の観点からユーザーエージェント文字列の廃止を進めています。
そこで登場したのが、「User-Agent Client Hints」という新しい仕組みです。
User-Agent Client Hintsを使えば、ユーザーエージェント文字列に頼らずに、ブラウザやデバイスの情報を取得できます。
□サンプルコード6:User-Agent Client Hintsの使用例
実行結果(例)
User-Agent Client Hintsを使うには、まずHTMLのタグでUser-Agent Client Hintsを有効化します。
というタグを使い、取得したい情報(UA、UA-Full-Version、UA-Mobileなど)を指定します。
すると、JavaScript側でnavigator.userAgentDataオブジェクトからそれらの情報を取得できるようになります。
例えば、navigator.userAgentData.brandsでブラウザ名とバージョン、navigator.userAgentData.mobileでモバイル端末かどうか、navigator.userAgentData.platformでOSといった具合です。
ユーザーエージェント文字列とは異なり、構造化されたデータとして情報が提供されるので、扱いやすいというメリットがあります。
ただし、User-Agent Client Hintsはまだ新しい技術で、すべてのブラウザで対応しているわけではありません。
特にInternet Explorerには対応していないため、利用には注意が必要です。
過渡期となる現状では、User-Agent Client Hintsとユーザーエージェント文字列の両方を併用しながら、徐々にUser-Agent Client Hintsへの移行を進めていくのがよいでしょう。
○サードパーティのユーザーエージェント判定APIを使う
ここまでは、主にフロントエンド(JavaScript)でのユーザーエージェント判定方法を見てきました。
しかし、ユーザーエージェント判定はサーバーサイドで行うこともできます。
その1つの方法が、サードパーティの「ユーザーエージェント判定API」を利用することです。
ユーザーエージェント判定APIとは、ユーザーエージェント文字列を送信すると、ブラウザやデバイスの情報を返してくれるWebサービスのことです。
□サンプルコード7:ユーザーエージェント判定APIの使用例
実行結果(例)
このサンプルコードでは、ユーザーエージェント判定APIの一例として「User Agent Info API」を使っています。
まず、getUserAgentInfo関数の中で、fetch関数を使ってUser Agent Info APIにリクエストを送信します。
その際、URLのパラメータとしてユーザーエージェント文字列(navigator.userAgent)を渡します。
すると、APIからはJSON形式でブラウザやデバイスの情報が返ってきます。
あとはそのデータを解析するだけで、簡単にユーザーエージェント判定ができるわけです。
APIを使う利点は、ユーザーエージェント文字列の解析をAPIに任せられること。
新しいブラウザやデバイスに対応するのもAPIの提供元に任せられるので、メンテナンスが楽になります。
ただし、APIを利用するためにはネットワーク通信が必要になります。
レスポンスを待つ必要があるため、同期的に判定結果を得ることはできません。
また、無料で使えるAPIには利用制限があることが多いので、大規模なサービスで使う場合はコストを検討する必要があります。
○HTTP_USER_AGENTサーバー変数を使う
もう1つ、サーバーサイドでユーザーエージェントを取得する方法が「HTTP_USER_AGENTサーバー変数」を使う方法です。
HTTP_USER_AGENTは、サーバーサイドでユーザーエージェント文字列を取得するための環境変数です。
クライアントからのHTTPリクエストのヘッダーに含まれるUser-Agentの値が格納されています。
□サンプルコード8:サーバーサイドでのユーザーエージェント取得
実行結果(例)
このサンプルコードはPHPで書かれていますが、実際にはどのサーバーサイド言語でも同様の方法が使えます。
$_SERVER[‘HTTP_USER_AGENT’]でユーザーエージェント文字列を取得し、あとはそれを解析するだけ。
JavaScript側からは何もする必要がないので、シンプルですね。
ただ、サーバーサイドでユーザーエージェントを判定する場合、判定結果をフロントエンドに伝える手段が必要になります。
HTTPレスポンスのヘッダーやボディに判定結果を埋め込んだり、JavaScriptからAjaxでサーバーに問い合わせたりする必要があります。
また、ユーザーエージェントの判定はできるだけフロントエンド側で行うほうがレスポンスが速いので、サーバーの負荷を下げるためにもクライアントサイドでの判定が推奨されています。
とはいえ、User-Agent Client Hintsのような新しい技術への対応が追いついていないケースでは、サーバーサイド判定が有効な場合もあります。
状況に応じて、適切な方法を選択しましょう。
○feature detectiuonを使う
さて、ここまでユーザーエージェントを使ったブラウザ判定の方法をいくつか見てきました。
しかし、実はユーザーエージェントを使わずにブラウザの判定を行う方法もあるんです。
その1つが「feature detection」という手法です。
feature detectionとは、ブラウザがある特定の機能に対応しているかどうかを判定することで、間接的にブラウザを判定する方法です。
□サンプルコード9:feature detectionによるブラウザ判定
実行結果(例:Chromeの場合)
このサンプルコードでは、各ブラウザに固有のオブジェクトや変数の存在を確認することで、ブラウザを判定しています。
例えば、Chromeの場合はwindow.chrome
オブジェクトとwindow.chrome.webstore
オブジェクトが存在するので、それをチェックしています。
FirefoxならInstallTrigger
オブジェクト、IEならDocument.documentMode
プロパティ、Safariならwindow.safari
オブジェクトの存在をチェックしています。
こうしたブラウザ固有の機能の有無を確認することで、ユーザーエージェントを使わずにブラウザを判定できるわけです。
feature detectionのメリットは、ユーザーエージェント文字列の解析よりもシンプルで直感的なコードで判定できること。
ユーザーエージェントの偽装の影響も受けにくいです。
ただし、網羅的にブラウザを判定するには、それぞれのブラウザの機能をよく知っておく必要があります。
また、新しいブラウザが登場した際には、その都度判定ロジックを追加していく必要があります。
ですから、feature detectionは主要なブラウザを判定する程度の用途には向いていますが、あまり細かなブラウザ判定が必要な場合には向いていないかもしれません。
○modernizrライブラリを使う
feature detectionを自前で実装するのは手間がかかります。
そこで、feature detectionを簡単に行うためのライブラリとして「modernizr」があります。
modernizrは、多数のブラウザ機能の対応状況を判定できるJavaScriptライブラリです。
modernizrを使えば、コードを書かなくてもブラウザの機能を簡単にチェックできます。
□サンプルコード10:modernizrによるfeature detection
実行結果(例:Chrome最新版の場合)
modernizrを使うには、まずHTMLでmodernizrのスクリプトを読み込みます。
すると、Modernizr
オブジェクトから各種のブラウザ機能の対応状況をチェックできるようになります。
例えば、Modernizr.websockets
でWebSocketの対応状況を、Modernizr.webgl
でWebGLの対応状況を判定しています。
このように、modernizrを使えば簡単にfeature detectionができるので、ブラウザ機能の互換性チェックに役立ちます。
modernizrはブラウザの判定というよりは機能の判定がメインですが、特定の機能の対応状況からブラウザを推測することもできます。
ただ、modernizrはかなり多くの機能をチェックするため、ライブラリのサイズが大きくなりがちです。
必要のない機能チェックは除外するなど、ライブラリのカスタマイズが必要になることもあります。
feature detectionはユーザーエージェントを使わないブラウザ判定の有力な手段ですが、用途に応じて適切な方法を選ぶことが大切ですね。
状況に合わせて、ユーザーエージェントとfeature detectionを使い分けるのがよいでしょう。
●ユーザーエージェント廃止の動きと今後の対応
ここまで、JavaScriptでユーザーエージェントを取得する様々な方法を見てきましたが、実は最近ユーザーエージェントをめぐる大きな変化が起きています。
それが、主要ブラウザでのユーザーエージェント文字列の廃止の動きです。
ユーザーのプライバシー保護の観点から、ユーザーエージェント文字列の詳細度を下げたり、ユーザーエージェントそのものを廃止する動きが加速しているのです。
○Chrome・EdgeなどでのUser-Agent廃止の背景
特にこの動きを主導しているのが、GoogleのChromeブラウザチームです。
Chromeチームは、ユーザーエージェント文字列が詳細すぎるデバイス情報を含んでおり、ユーザーのプライバシーを脅かす可能性があると考えています。
そこで、Chromeではユーザーエージェント文字列の情報量を徐々に減らす方針を打ち出しました。
具体的には、ユーザーエージェント文字列からOSのマイナーバージョンやデバイスのモデル名などの情報を削除していく予定です。
さらに将来的には、ユーザーエージェント文字列そのものを完全に廃止することを目指しています。
同じChromiumベースのMicrosoft Edgeなども、この方針に追随する見込みです。
これは、ユーザーエージェントに依存したブラウザ判定やデバイス判定に大きな影響を与えます。
従来の手法が使えなくなる可能性があるため、私たちWeb開発者は何らかの代替手段を探る必要に迫られているのです。
○User-Agent Clientや他の代替手段
ユーザーエージェント文字列の廃止を見据えて、いくつかの代替手段が提案されています。
1つは、先に紹介したUser-Agent Client Hintsです。
User-Agent Client Hintsは、ユーザーエージェント文字列の代わりにクライアントのブラウザ情報を提供する新しいAPIです。
ユーザーエージェントよりも構造化されたデータとして情報を取得できるのが特徴です。
ただし、User-Agent Client Hintsはまだすべてのブラウザで対応しているわけではありません。
過渡期の今は、ユーザーエージェントとUser-Agent Client Hintsを併用しながら、徐々に移行していくのがよいでしょう。
また、ユーザーエージェントに頼らずにブラウザ判定を行う手法としては、先ほど紹介したfeature detectionがあります。
ブラウザ固有の機能の有無をチェックすることで、間接的にブラウザを判定する方法です。
ユーザーエージェントの廃止が進む中、feature detectionの重要性はますます高まっていくと思われます。
modernizrのようなfeature detection用のライブラリも活用しながら、ユーザーエージェントに依存しないブラウザ判定の手法を身につけておくことをおすすめします。
いずれにしても、ユーザーエージェントの廃止は避けられない流れのようです。
私たちWeb開発者は、この変化を見据えて、適切な代替手段を探っていく必要がありますね。
柔軟な姿勢で新しい技術を取り入れながら、ユーザーエージェントに頼りすぎない堅牢なWebサイト設計を心がけていきたいものです。
●ユーザーエージェント判定の注意点
ユーザーエージェントを使ったブラウザ判定やデバイス判定は、とても便利な手法ですが、いくつか注意点もあります。
ここからは、ユーザーエージェント判定を行う際の注意点を2つ見ていきましょう。
○ユーザーエージェントは偽装可能
まず1つ目の注意点は、ユーザーエージェントが偽装可能だということです。
ユーザーエージェント文字列は、クライアント側のブラウザから送信されるものです。
つまり、ユーザーがブラウザの設定を変更したり、特殊なブラウザを使ったりすることで、任意のユーザーエージェント文字列を送信できてしまうのです。
例えば、UserAgent Switcher等の拡張機能を使えば、ChromeでもFirefoxのふりをしたり、iPhoneのふりをしたりできます。
悪意を持った人が、意図的に偽のユーザーエージェントを送信してくる可能性もあります。
ですから、ユーザーエージェントを使った判定は、あくまで「推測」に過ぎないことを理解しておく必要があります。
ユーザーエージェントが〇〇だからと言って、100%そのブラウザやデバイスだと断定はできないのです。
特にセキュリティ上重要な判定をユーザーエージェントだけで行うのは危険です。
例えば、特定のブラウザやデバイスでしかアクセスできないような機能制限をユーザーエージェントで行うと、偽装された場合に突破されてしまう恐れがあります。
大事なのは、ユーザーエージェントによる判定はあくまで補助的なものと捉えること。
過度に依存せず、他の手段と組み合わせるなどして、柔軟に対応することが求められます。
○ユーザーエージェントに依存しすぎない設計を
2つ目の注意点は、ユーザーエージェントに依存しすぎないWebサイト設計を心がけることです。
先ほども触れたとおり、ユーザーエージェントは将来的に廃止される方向にあります。
ChromeやEdgeなどの主要ブラウザが、ユーザーエージェント文字列を削除する計画を進めているのです。
もしWebサイトの機能がユーザーエージェントに大きく依存していたら、ユーザーエージェントの廃止によって致命的な問題が生じかねません。
例えば、ユーザーエージェントを使って特定のブラウザ専用の機能を提供していたとします。
ユーザーエージェントが使えなくなった時、その機能は機能しなくなってしまうかもしれません。
ですから、これからはユーザーエージェントに頼りすぎない設計を心がける必要があります。
例えば、レスポンシブWebデザインを採用して、ブラウザやデバイスの違いを吸収するのも1つの方法です。
また、ブラウザ判定が必要な場合は、ユーザーエージェントだけに頼るのではなく、feature detectionと組み合わせるなどの工夫が大切です。
modernizrのようなfeature detection用のライブラリを活用するのもよいでしょう。
いずれにしても、ユーザーエージェント文字列はいつ使えなくなってもおかしくない存在だということを認識しておく必要があります。
私たちWeb開発者は、ユーザーエージェントに過度に依存することなく、よりブラウザやデバイスに依存しないWebサイト設計を追求していかなければならないのです。
そうすることで、ユーザーエージェントの変化にも柔軟に対応できるはずです。
ユーザーエージェントを活用しつつも、その限界と未来を見据えた設計を心がける。
それが、これからのWeb開発に求められる重要な視点ではないでしょうか。
まとめ
本記事では、JavaScriptでユーザーエージェントを取得する10の方法と、ユーザーエージェント廃止の動向について詳しく解説しました。
過度にユーザーエージェントに依存せず、ブラウザやデバイスの違いを吸収できる柔軟な設計を心がけることが大切です。
ユーザーエージェントを適材適所で活用しつつ、その限界を理解し、時代の変化に適応していく姿勢が、これからのWeb開発者に求められています。