JavaScriptで使用ブラウザを判定させたい

目次
  1. 結論
  2. ブラウザを判定する方法
  3. 確実ではないがそれなりに判定は可能
  4. 使用ブラウザを偽装してみる
  5. 今後のUserAgentに関する動き
  6. 参考

Webアプリ開発ではブラウザの差異によって微妙な解釈違いがあり、フロントエンジニアの悩みの種になることが多々あると思います。

せめて使用ブラウザを判定して、推奨ブラウザへ誘導するような処理を実装したい… そういう思いでブラウザ判定処理について調べてみました。

結論

確実な使用ブラウザの判定方法はありません😫

ブラウザを判定する方法

JavaScriptでは、window.navigator.userAgentに使用しているブラウザ情報が格納されています。

その値を部分一致なりで判定して、ブラウザ毎に分岐処理をするという方法で使用ブラウザを判定することになりますが、 userAgentの値は、ブラウザの開発者によって指定される値で、厳密に決められたルールは存在しません。

最古のブラウザNCSA MosaicからUserAgentは存在しましたが、後方互換性の問題等で記述内容が複雑化し今に至っています。 例えば、ChromeのUserAgentに何故かMozilla/**という文字列が含まれているのは、かつてMozilla、Mosaicが幅を利かせていた時代、UserAgentは両者のいずれかが前提で動作するWebサイトが多く、後発のIEはMozillaに偽装する必要があったからだそうですね。

話が逸れましたが、つまりはUserAgentは偽装が可能です。 Chromeと同じものに指定しまえば、Chromeを装うことも可能になっています。

確実ではないがそれなりに判定は可能

https://github.com/faisalman/ua-parser-js

https://github.com/bestiejs/platform.js/

有名なブラウザ判定ライブラリにUAParser.js, Platform.jsというものがあります。

どちらもuserAgentの値を解析して、実際の使用ブラウザに近い値を出力しているようです。

UAParser.jsの方が頻繁にGitHubへのコミットが盛んでStar数も多いことから 個人的には採用するならUAParser.jsになるかなと思います。

下記のUAParse.jsによるデモページを開くと、解析結果を見ることができます。 http://faisalman.github.io/ua-parser-js/

使用ブラウザを偽装してみる

せっかくなので、userAgentを自分で偽装してみます。 Chromeの開発者ツールを使うと簡単に偽装が可能です。 今回はUAParse.jsのデモページを例に使わせてもらいます。

手順

  • デモページを開く http://faisalman.github.io/ua-parser-js/

  • F12を押し、開発者ツールを開く

  • Toggle Device Toolverをクリック

  • エミュレートする端末を選択(例ではiPhone Xを選択)

  • F5でページを再読み込みする

iOSのSafariで閲覧しているとUAParse.jsは判断しました。 (実際はWindows10のChromeで閲覧)

これはChromeによってuserAgentが Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 に置き換えられた為です。

userAgentによる分岐処理をデバッグをする際には、便利な機能ですね。

今後のUserAgentに関する動き

将来的にUserAgentを凍結する動きが出てきています。 背景にはやはりUserAgentの値が複雑化してしまっているという問題があるようですね。

Chromeは本来2020年中にUserAgent凍結をする予定でしたが、COVID-19の影響で2021年に延期されています。(執筆日2020/12/29時点の情報)

Safariはいち早く凍結したようですね。流石Apple、仕様変更に微塵も躊躇が無い。

一方でWICGではUserAgentに代わる仕様としてUA-CH(User Agent Client Hints)という仕組みを策定中です。 詳細は下記で見れます。 https://github.com/WICG/ua-client-hints

参考

https://www.infoq.com/jp/news/2020/08/chrome-phasing-user-agent/

https://ics.media/entry/200729/