JavaScriptでユーザーが利用しているWebブラウザを判定して処理を変える


Webサイトを構築していく中でユーザーが利用しているWebブラウザによって処理を変えたいことがあります。
そうした場合にはJavaScriptで条件分岐をさせて処理を変える方法をとっていきます。

例えば、JavaScriptのプログラムがWebブラウザで挙動が違ったりうまく動かないといった時に、JSファイルをブラウザによって切り替えるといった対応をすることができます。

ここではJavaScriptでユーザーが利用しているWebブラウザを判定して処理を変える方法をご紹介します。

ユーザーの取得には、userAgentプロパティuserAgentDataプロパティと、2種類のプロパティを利用していきます。
userAgentは廃止予定ですので、今後はuserAgentDataを利用していくことになってきますが、まだuserAgentDataが有効でないブラウザもありますので、両方の方法でご紹介していきます。

ブラウザ情報を取得する


JavaScriptでユーザーが利用しているWebブラウザの情報を取得するには「window.navigator.userAgent」を使います。navigatorオブジェクトのuserAgentプロパティでユーザーがアクセスした時のユーザー情報が取得できますので、そのユーザーの情報からブラウザの情報を確認します。

const ua = window.navigator.userAgent;
console.log(ua);



処理の結果はconsole.log()でWebブラウザのコンソールに結果を表示させています。

実際にGoogle Chromeでデベロッパーツールを起動してコンソールを確認すると以下のようにGoogle Chromeでアクセスした結果が確認できます。

JavaScriptでブラウザ情報を取得



各Webブラウザの結果では以下のように情報が取得できます。

Google Chrome
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36

FireFox
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:64.0) Gecko/20100101 Firefox/64.0

Microsoft Edge
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763

Chromium版 Microsoft Edge
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36 Edg/79.0.309.65

Microsoft Internet Explorer
Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko

Safari
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.2 Safari/605.1.15

Opera
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 OPR/57.0.3098.106


この情報を元にWebブラウザの判定を行って処理を変えます。
しかし、各ブラウザの出力結果を見ていただくとわかると思いますが、Google ChromeでSafariの文字列が入っていたり、Microsoft EdgeやOperaでChromeとSafariの文字列が入っていたりします。

また、2020年1月からリリースされたChromium版のMicrosoft Edgeでも、「Edge」と「Edg」と違いがありますので、新旧ブラウザの判別には気をつけてください。macOS版のMicrosoft EdgeもWindowsと同じです。

これから出力結果の文字列を元にブラウザ判定を行いますが、複数のブラウザの文字列が含まれてくることも計算した上で条件分岐を行っていきます。

ブラウザを判定して処理を変える


ブラウザを判定をユーザーエージェントの情報を元に行っていきますが、ブラウザの情報の文字列で判断していきます。そして文字列を判断するためにindexOf()メソッドを使います。

indexOfメソッドは文字列内に指定した文字列が含まれているか検索するメソッドになります。
引数に検索する文字列を記述してマッチする文字列を探します。見つからなければ-1を返します。

userAgentの情報を入れた変数からindexOfメソッドで文字列を検索し、-1でなければ指定した検索文字列が見つかったので、その文字列を含んでいる場合の処理として条件分岐させます。
文字列の大文字と小文字は区別されるので気をつけてください。

const ua = window.navigator.userAgent;
 
if(ua.indexOf('Edge') != -1 || ua.indexOf('Edg') != -1) {
  console.log('Microsoft Edge');
} else if(ua.indexOf('Trident') != -1 || ua.indexOf('MSIE') != -1) {
  console.log('Microsoft Internet Explorer');
} else if(ua.indexOf('OPR') != -1 || ua.indexOf('Opera') != -1) {
  console.log('Opera');
} else if(ua.indexOf('Chrome') != -1) {
  console.log('Google Chrome');
} else if(ua.indexOf('Firefox') != -1) {
  console.log('FireFox');
} else if(ua.indexOf('Safari') != -1) {
  console.log('Safari');
} else {
  console.log('Unknown');
}



Internet ExplorerやOperaブラウザは古いバージョンを利用していると違いがありますので、OR条件で複数の指定しておきます。
あとは記述する順番を気をつけてもらえば各ブラウザの判断を間違えることはないでしょう。

1つ、サンプルとしてWebブラウザによって読み込むJSファイルを変えるといったサンプルコードを用意しました。
例えばInternet ExplorerやEdgeといったMicrosoft製のブラウザだけうまくJavaScriptが動かないなんてことがあったとして、IEとEdgeだけは別のJSファイルを読み込んで、その他のブラウザは従来のJSファイルを読み込ませるといった条件分岐になります。

<script>
  const ua = window.navigator.userAgent;
 
  if(ua.indexOf('Edge') != -1 || ua.indexOf('Edg') != -1 || ua.indexOf('Trident') != -1 || ua.indexOf('MSIE') != -1) {
    document.write('<script src="js/script-ms.js"><\/script>');
  } else {
    document.write('<script src="js/script.js"><\/script>');
  }
</script>



条件によってdocument.writeでHTMLでタグを出力しています。
タグを出力する際にはシングルクォーテーションとダブルクォーテーションの入れ子とscriptの終了タグのスラッシュ「/」をバックスラッシュ「\」でエスケープ処理をするのに気をつけてください。
JavaScriptを読み込ませるheadタグまたはbodyの終了タグの直前などに記述してもらえれば良いかと。

もちろんCSSの読み込みの制御にも利用できるでしょう。CSSの場合はCSSハックで制御する方もいるかと思いますが。

Internet Explorerのバーションで処理を変えたい場合では「MSIE 10」や「MSIE 9」といった文字列検索で対応することができます。その場合は変数を「let」ではなく「var」で宣言してください。古いバージョンのブラウザはletが対応していないので。

IE 10
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)

IE 9
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)

User Agent Client Hintsによる情報の取得


セキュリティや個人情報の保護の観点からuserAgentは廃止となる流れで、今後はUser Agent Client Hints(UA-CH)で判定していくことになっていくことになるでしょう。

User-Agent Client Hintsが有効なブラウザの場合、JavaScriptでは「navigator.userAgentData()」で情報を取得することができます。
navigator.userAgentData()は、User-Agent Client Hints APIにアクセスしてNavigatorUADataオブジェクトを返します。
console.log()で値を確認しながら見ていきます。

const uaData = navigator.userAgentData;
console.log(uaData);



以下、実行結果になります。

User Agent Client Hints(UA-CH)による情報の取得



brandsやmobile、platformの情報が並列で返ってくるのが確認できます。

brands: ブラウザーの種類・バージョン情報
mobile: モバイル端末かどうかの情報
platform: OSの情報



また「.userAgentData.brands」とすることで、brandsの情報だけを取得することもできます。

const uaData = navigator.userAgentData.brands;
console.log(uaData);



さらに細かく情報を取得したい場合は、getHighEntropyValues()メソッドで情報を取得していくこともできます。
以下のような引数を指定して、CPUアーキテクチャ情報やデバイスモデル情報などの細かな情報も取得できます。

"architecture"
"bitness"
"model"
"platformVersion"
"uaFullVersion" 
"fullVersionList"



以下、サンプルプログラムになります。
await非同期処理の処理を待ってから実装しますが、awaitはasync関数内のみでの使用となりますので、async関数で実行していきます。
試しに、OSの情報を取得してみます。

const uaData = navigator.userAgentData;
(async () => {
  const highEntropyValues = await uaData.getHighEntropyValues([
    "platform",
    "platformVersion",
    "architecture",
    "model",
    "uaFullVersion",
  ]);
  console.log("情報", highEntropyValues);

  // OSの情報
  const platform = highEntropyValues.platform;
  console.log(platform);

  // OSのバージョン情報
  const platformVersion = highEntropyValues.platformVersion;
  console.log(platformVersion);
})();



highEntropyValuesから「platform」の値を指定すればOSの情報が取得できますし、「platformVersion」の値を指定すればOSのバージョン情報が取得できます。

getHighEntropyValues()メソッドでuserAgentDataの細かな情報を取得する

User Agent Client Hintsでブラウザを判定


それでは、User Agent Client Hintsでブラウザを判定してみましょう。

User-Agent Client Hintsがまだ有効でないブラウザもあります。
すべての環境に適応できるように有効のブラウザと無効のブラウザで処理を切り分けるといいでしょう。

if文の条件を「window.navigator.userAgentData」として判別していきます。

if (window.navigator.userAgentData) {
  // userAgentDataで判定する(userAgentDataが有効)
} else {
  // userAgentで判定する(userAgentDataが無効)
}


無効の場合は従来のuserAgentで処理をします。

以下、サンプルコードになります。

if (window.navigator.userAgentData) {

  const uaData = navigator.userAgentData;
  console.log(uaData);

  //  利用ブラウザーの情報
  const brand = uaData.brands[2].brand;

  if(brand.indexOf('Edge') != -1) {
    console.log('Microsoft Edge');
  } else if(brand.indexOf('Chrome') != -1) {
    console.log('Google Chrome');
  } else if(brand.indexOf('Firefox') != -1) {
    console.log('FireFox');
  } else if(brand.indexOf('Safari') != -1) {
    console.log('Safari');
  } else {
    console.log('Unknown');
  }

} else {

  const ua = window.navigator.userAgent;
  console.log(ua);

  if(ua.indexOf('Edge') != -1 || ua.indexOf('Edg') != -1) {
    console.log('Microsoft Edge');
  } else if(ua.indexOf('Trident') != -1 || ua.indexOf('MSIE') != -1) {
    console.log('Microsoft Internet Explorer');
  } else if(ua.indexOf('OPR') != -1 || ua.indexOf('Opera') != -1) {
    console.log('Opera');
  } else if(ua.indexOf('Chrome') != -1) {
    console.log('Google Chrome');
  } else if(ua.indexOf('Firefox') != -1) {
    console.log('FireFox');
  } else if(ua.indexOf('Safari') != -1) {
    console.log('Safari');
  } else {
    console.log('Unknown');
  }

}


「uaData.brands[2].brand」は、brandの多次元配列からbrand情報を取り出しています。
「[2]」のキー「brand」を指定してブラウザ情報が取得できます。
他にもメソッドを使ってbrand情報を取得してもいいですが、メソッドが動かないブラウザもあるかもしれないので、ここは正攻法で多次元配列の値の取得方法のプログラムのほうが正確でしょう。

ブラウザの情報が取得できましたら、あとはindexOf()などでブラウザごとに処理を切り分けることができます。

以下、console.log()の実行結果です。

User Agent Client Hintsでブラウザを判定

まとめ


userAgentの廃止が進み、今後はUser Agent Client Hintsを利用していくことになりますので、ユーザー情報で処理の切り分けが必要な部分は早めに対応しておくと良いでしょう。
サポートが終了するInternet Explorerや同じくらいシェア率の低いOperaは、もう無視してもいいかもしれませんね。

また、WordPressなどPHPが利用できる環境でしたらサーバサイドでの処理のほうがJavaScriptが無効に設定されているユーザーにも対応できますので、PHPでのブラウザ判定をされると良いでしょう。

PHPでのブラウザ判定の方法はこちらで紹介していきます。

↓ ↓ ↓

PHPでユーザーが利用しているWebブラウザを判断して処理を変える