この翻訳は不完全です。英語から この記事を翻訳 してください。

ブラウザー別に異なるウェブページまたはサービスを提供するのは、ふつうは良いことではありません。ウェブは使用しているブラウザーや機器に関係なく、誰からでもアクセスできるようになっています。特定のブラウザーを対象にするのではなく、機能の可用性の観点からウェブサイトを継続的に改良するために改善する方法はあります。

しかし、ブラウザーや標準は完全ではなく、ブラウザーの判定を必要とする場合が稀にあります。User agent を使用してブラウザーを検出することは簡単に見えますが、うまくその様にすることは、実は、とても難しい問題です。このドキュメントは、これをできるだけ正しく行う方法を案内します。

繰り返し言います。User agent を調べることが良い考えであることは稀です。問題を解決するには、もっと良い、もっと広く互換性のある方法が見つかるはずです。

ブラウザーの検出を用いる前に考えること

User agent の文字列を使用して使用されているブラウザを検出することを検討している場合は、できればまずは回避するようにしてください。なぜそれをやりたいのかを認識することから始めます。

あるバージョンのブラウザで特定のバグを回避しようとしていますか?
専門のフォーラムで見てみるか、尋ねてみましょう:あなたがこの問題に最初に遭遇することはまずありません。また専門家、あるいは単に別の視点を持つ人々は、バグを回避するためのアイディアをあなたに与えることができます。問題が珍しい場合は、このバグがバグ追跡システム (Mozilla; WebKit; Blink; Opera) を介してブラウザベンダーに報告されているかどうかを確認することが重要です。ブラウザメーカーはバグレポートに注意を払い、そのバグの他の回避策を分析するかもしれません。
特定の機能の存在を確認しようとしていますか?
サイトによっては、まだサポートされていない Web 機能を使用する必要があり、一部のユーザーを機能は少ないが動作することがわかっている古い Web サイトに送信したい場合があります。これは User agent の検出を使用する最悪の理由です。なぜならオッズは他のすべてのブラウザが最終的に追いつくからです。さらに、それほど一般的でないブラウザを1つ1つ全てテストするのは現実的ではありません。User agent の盗聴は決して行うべきではありません。代わりに機能の検出を常に行います。
使用されているブラウザによって異なる HTML を提供しますか?
通常では悪い慣例ですが、これが必要な場合もあります。このような場合は、まず自分の状況を分析してそれが本当に必要であることを確認する必要があります。意味のない <div> 要素か <span> 要素を追加することでそれを防ぐことができますか? User agent の検出をうまく使用することの難しさは HTML の純度をいくらか損なうだけの価値があります。また、デザインを再考してください:プログレッシブなエンハンスメントや流体レイアウトを使用して、これを行う必要性を取り除くことができますか?

ユーザーエージェントの検出の回避

User agent の検出を使用しないようにしたい場合は、いくつかのオプションがあります。

機能の検出
機能の検出とは、ページを表示しているブラウザを特定しないで、必要な機能が利用可能かどうかを確認することです。そうでない場合は、フォールバックを使用します。API の動作を異なる方法で実装するブラウザを検出するなど、User agent 文字列を使用する必要があるまれなケースはまったくありません。むしろ、このようなまれなケースでは、ブラウザが API をどのように実装しているかを検出し、代わりにいつどのように使用するかを決定するテストを実装する必要があります。特徴検出の良い現在の例は以下の通りです。直近で Chrome では正規表現のサポートが実験的に追加されましたが、他のブラウザではこれをサポートしていません。したがって、あなたはこれを行うべきであると誤って想定するかもしれません:
if (navigator.userAgent.indexOf("Chrome") !== -1){
    // YES, the user is suspected to support look-behind regexps 
} else { /*put your old fall back code here*/ }

しかし、上記のコードは絶対にひどいものであり、分かりにくいものです。Chrome がこの外観保護機能を削除した場合はどうなりますか? 別のブラウザで regexps の背後にルックを実装するとどうなりますか? 他のブラウザが User agent 文字列で Chrome を使用している場合はどうなりますか? このリストは、ひどく間違っているかもしれないことを繰り返します。したがって、代わりに次のような機能検出を使用する必要があります。

var isLookBehindSupported = false;
try { isLookBehindSupported = !!new RegExp("(?<=)"); } catch (e) {
/*In unsupported browsers, trying to create a lookbehind expression will simply error, which is caught here*/
}
if (isLookBehindSupported) {
    // Yay, lookbehind expressions are supported
} else {
    // Booo! Lookbehind not supported
}

上記のコードが示すように、例外を除いて、ブラウザのサポートをテストする方法は常にあります。このためにユーザーの文字列をチェックする理由はありません

最後に、上記のコードスニペットは、常に考慮しなければならないクロスブラウザのコーディングで重大な問題を引き起こします。サポート対象外のブラウザでテストしている API を意図せず使用しないでください。これは明らかでシンプルに聞こえるかもしれませんが、そうでない時もあります。たとえば、上記のコードスニペットでは、短い regexp 表記 (たとえば /reg/igm) で lookbehind を使用すると、サポートされていないブラウザで parser エラーが発生します。したがって、あなたのコードの lookbehind がサポートされているセクションであっても、上記の例では /(?<=look_behind_stuff)/ の代わりに new RegExp("(?<=look_behind_stuff)"); を使用します。

漸進的強化
この設計手法では Web サイトを「レイヤー」で開発し、ボトムアップのアプローチを使用し、より簡単なレイヤーから始めて、それぞれがより多くの機能を使用する連続したレイヤーでサイトの機能を向上させます。
優雅な劣化
これは、必要なすべての機能を使用して最適なサイトを構築し、それを古いブラウザでも使用できるように調整するトップダウンアプローチです。これは、漸進的強化よりも難しく、有効性が低いですが、場合によっては有用である可能性があります。
モバイルデバイスの検出
おそらく User agent のスニッフィングの最も一般的な使用と誤用は、そのデバイスがモバイルデバイスであるかどうかを検出することです。しかし、責任を負うことができないのは、彼らが本当に後にしていることです。開発者は User agent のスニッフィングを使用して、ユーザーのデバイスがタッチフレンドリーで画面が小さいかどうかを検出し、それに応じてウェブサイトを最適化することができます。User agent のスニッフィングではこれらを検出することがありますが、すべてのデバイスが同じではありません。モバイルデバイスの中には大きな画面サイズがあり、デスクトップの中には小さなタッチスクリーンがあり、一部の人々はまったく異なる野球ゲームであるスマートテレビを使用している人もいます。だから、User agent のスニッフィングは確実な方法ではありません。しかし、はるかに良い選択肢があります。Navigator.maxTouchPoints を使用して、ユーザーのデバイスにタッチスクリーンがあるかどうかを検出します。次に、if (!("maxTouchPoints" in Navigator)) { /*Code here*/} がある場合に限り、デフォルトでユーザーエージェントの画面をチェックするように戻ります。デバイスにタッチスクリーンがあるかどうかはこの情報を使用して確認できますが、タッチデバイスだけのためにウェブサイトのレイアウト全体を変更しないでください。より多くの作業とメンテナンスを自分でやることになります。むしろより大きく、より簡単にクリック可能なボタンなどの便利な機能を追加します (CSS を使用すると、フォントサイズを単純に増やすことができます)。画面のサイズは、単にwindow.innerWidth と window.addEventListener("resize", function(){ /*refresh screen size dependent things*/ }) を使用してください。あなたが画面サイズのためにやりたいことは、より小さな画面の情報を削っていません。デスクトップバージョンを使用するようになるので、人々を悩ますだけです。むしろ、小さい画面で長いページでは情報の列数を少なくし、画面サイズが大きいほど短いページで多くの列を持つようにしてください。この効果は、CSS Flex box を使用して簡単に達成できます。次に、コードを常に動的にします。ユーザーは、ページの幅と高さを変更して、携帯端末を横に振りかけることができます。開発ツールのサイドパネルを開いて、ウェブページが滑らかで流動的で動的にサイズ変更されている間に画面のサイズを変更するまで、あなたのウェブページには満足しないでください。

あなたが探している情報が含まれているユーザエージェントの部分

User Agent 文字列の異なる部分の統一性がないので、これは難しい部分です。

ブラウザ名

開発者が「ブラウザ検出」をしたいと言うと、実際には「レンダリングエンジンの検出」がしばしば必要です。SeaMonkey や Chromium とは対照的に、Firefox を実際に検出したいのですか?またはブラウザが Gecko または WebKit レンダリングエンジンを使用しているかどうかを実際に見たいだけですか?これが必要な場合は、さらにページを見てください。

ほとんどのブラウザは、Internet Explorer の例外を除いて、BrowserName/VersionNumber の形式で名前とバージョンを設定します。しかし、名前がその形式の User Agent 文字列内の唯一の情報ではないので、ブラウザの名前を見つけることができず、探している名前があるかどうかを確認することしかできません。しかし、一部のブラウザは嘘をついていることに注意してください。たとえば、Chrome は Chrome と Safari の両方を報告します。だから、 Safari の文字列と Chrome 文字列がないことを確認する必要がある Safari を検出するには、Chromium が Chrome として報告するか、Seamonkey が Firefox として報告することがあります。

また、BrowserName に単純な正規表現を使用しないように注意してください。User Agent には、Keyword/Value 構文以外の文字列も含まれています。Safari&Chrome には、'Gecko' のような文字列が含まれています。

  含む 含まない  
Firefox Firefox/xyz Seamonkey/xyz  
Seamonkey Seamonkey/xyz    
Chrome Chrome/xyz Chromium/xyz  
Chromium Chromium/xyz    
Safari Safari/xyz Chrome/xyz or Chromium/xyz Safari gives two version number, one technical in the Safari/xyz token, one user-friendly in a Version/xyz token
Opera

OPR/xyz [1]

Opera/xyz [2]

 

[1] Opera 15+ (Blink-based engine)

[2] Opera 12- (Presto-based engine)

Internet Explorer ; MSIE xyz;   Internet Explorer doesn't put its name in the BrowserName/VersionNumber format

もちろん、Chrome が過去に Safari の文字列をハイジャックしたなど、他のブラウザがこれらのものの一部をハイジャックすることは絶対に保証されていません。そのため、User Agent 文字列を使用したブラウザの検出は信頼性が低く、バージョン番号のチェック (過去のバージョンのハイジャックはあまりありません) でのみ行う必要があります。

ブラウザのバージョン

ブラウザのバージョンは、常にそうとは限りませんが、User Agent  文字列の BrowserName/VersionNumber トークンの値部分に入れられることがよくあります。 もちろんこれは Internet Explorer (MSIE トークンの直後にバージョン番号を入れる) ではなく、Version/VersionNumber トークンを追加したバージョン 10 以降の Opera に当てはまります。

もう一度、探しているブラウザの正しいトークンを取ってください。他の人に有効な番号が含まれるという保証はありません。

レンダリングエンジン

前述のように、ほとんどの場合、レンダリングエンジンを探す方が良い方法です。 これは、あまり知られていないブラウザを除外しないために役立ちます。 共通のレンダリングエンジンを共有しているブラウザは、同じ方法でページを表示します。一方で動作するものは、もう一方ではうまくいくという正当な前提があります。

主なレンダリングエンジンには、Trident、Gecko、Presto、Blink、WebKitの5つがあります。 レンダリングエンジンの名前を盗聴するのが一般的であるため、多くのユーザエージェントが検出をトリガーするために他のレンダリング名を追加しました。 したがって、レンダリングエンジンを検出する際に偽陽性を引き起こさないように注意することが重要です。

  Must contain  
Gecko Gecko/xyz  
WebKit AppleWebKit/xyz Pay attention, WebKit browsers add a 'like Gecko' string that may trigger false positive for Gecko if the detection is not careful.
Presto Opera/xyz Note: Presto is no longer used in Opera browser builds >= version 15 (see 'Blink')
Trident Trident/xyz Internet Explorer put this token in the comment part of the User Agent String
Blink Chrome/xyz  

レンダリングエンジンのバージョン

ほとんどのレンダリングエンジンは、Gecko を除いて RenderingEngine/VersionNumber トークンにバージョン番号を入れます。Gecko は rv: 文字列の後の User Agent のコメント部分に Gecko のバージョン番号を入れます。モバイル版の Gecko 14 とデスクトップ版の Gecko 17 から、この値を Gecko/version トークン (以前のバージョンではビルド日付、その後 GeckoTrail と呼ばれる固定日付) に置きます。

OS

オペレーティングシステムは、ほとんどのユーザーエージェント文字列(Firefox OSのようなWebベースのプラットフォームではありません)で提供されますが、形式は大きく異なります。 これは、ユーザーエージェントのコメント部分にある2つのセミコロン間の固定ストリングです。 これらの文字列は、各ブラウザに固有です。 それらはOSを示していますが、依存するハードウェアのバージョンと情報(32ビットまたは64ビット、またはIntel / PPC for Mac)もしばしば表示されます。

すべての場合と同様に、これらの文字列は将来変更される可能性があります。すでにリリースされているブラウザの検出と組み合わせて使用する必要があります。 新しいブラウザのバージョンが出てくるときにスクリプトを適合させるための技術調査が必要です。

モバイル、タブレットもしくはデスクトップ

ユーザーエージェントのスニッフィングを実行する最も一般的な理由は、ブラウザが実行されているデバイスの種類を判断することです。 目標は、さまざまなデバイスタイプに異なるHTMLを提供することです。

  • ブラウザやレンダリングエンジンは、1種類のデバイスでしか動作しないと想定しないでください。 特に、異なるブラウザやレンダリングエンジンに異なるデフォルトを設定しないでください。
  • ブラウザがモバイル、タブレット、またはデスクトップのいずれであるかを定義するために、OS トークンを使用しないでください。OS は複数のタイプ (Android はタブレットや携帯電話など) で動作します。

次の表はメジャーなブラウザのベンダーが、ブラウザがモバイルデバイス上で動作していることを示す方法をまとめたものです。

各ブラウザの User Agent 文字列
ブラウザ ルール
Mozilla (Gecko, Firefox) Mobile or Tablet token in the comment. Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0
WebKit-based (Android, Safari) Mobile Safari token outside the comment. Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Blink-based (Chromium, Google Chrome, Opera 15+) Mobile Safari token outside the comment Mozilla/5.0 (Linux; Android 4.4.2); Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047
Presto-based (Opera 12-)

Opera Mobi/xyz token in the comment (Opera 12-)

Opera/9.80 (Android 2.3.3; Linux; Opera Mobi/ADR-1111101157; U; es-ES) Presto/2.9.201 Version/11.50

Internet Explorer IEMobile/xyz token in the comment. Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)

要約すると、モバイルエージェントを検出するには、ユーザエージェントのどこかに文字列 "Mobi" があるかどうかを探すことをお勧めします。

デバイスの大きさが "Mobi" と表示されていない場合は、デスクトップサイトを提供する必要があります (デスクトップマシンにタッチスクリーンが表示されるように、タッチ入力をサポートするのがベストプラクティスです)。

ドキュメントのタグと貢献者

このページの貢献者: silverskyvicto, mfuji09, karaage-kun
最終更新者: silverskyvicto,