Internet ExplorerとSafari、Operaを判別する: 目指せウェブマスター

Internet ExplorerSafariOperaを判別する方法について説明します。
 ブラウザを完璧に判別するのは難しいのですが、基本的にuserAgentに含まれる文字列でブラウザを調べていきます。含まれる文字列を調べる場合には正規表現を使う方法と単純な文字列検索を使う方法があります。単純に特定の文字列が含まれるかどうか調べればよいので、indexOf()を使って調べます。indexOf()は以下の書式になります。

www.openspc2.org/kouza_js/071/

検索対象文字列.indexOf(検索文字列,検索位置)

 今回はuserAgentが検索対象文字列になります。検索位置は省略することができ、省略した場合は先頭(ゼロ)になります。
 検索文字列が特定のブラウザを示すものになりますが、Internet ExplorerSafariのuserAgentが返す文字列は以下のようになります。上がInternet Explorerで下がSafariになります。

Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ja-jp) AppleWebKit/103u (KHTML, like Gecko) Safari/100

 Internet Explorerの場合はMSIEという文字列があるかどうか調べます。userAgent内では他にInternet Explorerを示す文字列がないためです。Safariの場合にはuserAgent内にSafariの文字列があるかどうか調べます。
 実際のスクリプトは以下のようになります。ボタンをクリックするとブラウザ名が表示されます。









 次にOperaブラウザも判別してみます。Operaが返すuserAgentの文字列は以下のようになります。

Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.1) Opera 7.01 [en]

 OperaInternet Explorerではないにも関わらずMSIEという文字が含まれています。ブラウザは過去の経緯によりシェアの多いブラウザだと思わせるようにappName、appVersion、userAgentが返す文字列を詐称(いつわる)する事が多々あります。ブラウザ判別プログラムが複雑になってしまうのは、このようなシェア争いの経緯による所もあります。
 しかし、複雑になってしまってもどうしようもないので、うまく判別していくしかありません。上記のスクリプトではOperaInternet Explorerになってしまいますので、ここにOperaを判別するためuserAgent内にOperaの文字列があるかどうか調べます。
 実際のスクリプトは以下のようになります。









 注意しないといけないのは以下のように先にInternet Explorerを判別するとOperaであってもInternet Explorerになってしまう事です。


function checkBrowser()
{
var uName = navigator.userAgent;
if (uName.indexOf("Safari") > -1) return "Safari";
if (uName.indexOf("MSIE") > -1) return "Internet Explorer";
if (uName.indexOf("Opera") > -1) return "Opera";
return "Netscape";
}

 確実に、それと判別できるブラウザからチェックしていくのがポイントです。特に新しいブラウザは過去のブラウザ名を返すことが多いため、基本的に最新のブラウザからチェックしていきます。サンプルではいずれも該当しない場合にはNetscapeとしていますが、本当はもっとしっかりと判別する必要があります。ただ、Netscape自体の役割、シェアとも低くなっているため様子を見てスクリプトを作るのが良いでしょう。

Internet Explorerのバージョンを判別する」

 今回はInternet Explorerのバージョン判別する方法について説明します。
 前々回に掲載したInternet Explorerが返すappName, appVersion, userAgentは以下の文字列を返します。


Windows XP + Internet Explorer 6
navigator.appName : Microsoft Internet Explorer
navigator.appVersion : 4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)
navigator.userAgent : Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)

MacOS X + Internet Explorer 5.22
navigator.appName : Microsoft Internet Explorer
navigator.appVersion : 4.0 (compatible; MSIE 5.0; Macintosh; I; PPC)
navigator.userAgent : Mozilla/4.0 (compatible; MSIE 5.22; Mac_PowerPC)


 appVersionまたはuserAgentにバージョンが含まれていますが、appVersionではMacの場合には正確なバージョンを取得することができません。バージョンを取得するにはuserAgentに含まれる文字列からバージョン部分を抜き出すことになります。

 他のInternet Explorerのバージョンが返すuserAgentも見てみます。

Internet Explorer 4
Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)
Mozilla/4.0 (compatible; MSIE 4.5; Mac_PowerPC)

Internet Explorer 5
Mozilla/4.0 (compatible; MSIE 5.0; Windows 98)
Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)

 これらを見ると、いずれもMSIEの文字列の後にバージョン番号がありバージョン番号の後には;(セミコロン)がありますので、この範囲を抜き出せば良いことになります。
 indexOf()、lastIndexOf()、RegExpなどを使って一致文字列を調べてからsubstring、substr、RegExpでバージョン部分を文字列を抜き出します。indexOf()は文字列の前方から一致文字を調べ一致した位置を返します。また、indexOf()は文字列のどこから検索するかを指定できます。これを利用して、まずMSIEの文字を検索します。一致文字列があったら、そこを検索の開始位置として;(セミコロン)を検索します。この範囲をsubstringで抜き出します。
 他にも方法はありますが、indexOf()はRegExp(正規表現)と異なり、JavaScriptをサポートしているどのブラウザでも動作するため、最も安全に使うことができます。

 実際のプログラムは以下のようになります。









 これ以外の方法でもInternet Explorerのバージョンを抜き出すことができます。
 
Internet Explorerのバージョンを別の方法で判別する」

 前回はInternet Explorerのバージョンを抜き出すプログラムを作成しました。
 今回は前回のプログラムとは別の方法でバージョンを抜き出す方法を説明します。
 何かしたい場合に答えは1つではないので、いろいろな方法を考えてみると勉強になります。

 まず、Internet Explorer 6が返すuserAgentの文字列は以下のようになっています。

Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)

 前回はMSIEから;に続く部分を抜き出しました。この文字列をよく見ると半角空白で区切られています。半角空白ごとに分割してバージョン部分だけ抜き出せば簡単です。半角空白で分割するにはsplit()を使います。分割された結果は配列として返されます。バージョン部分は4番目になるので配列の4番目を見ればよいことになります。数値として返したい場合にはeval()またはparseFloat()を使います。
 実際のプログラムは以下のようになります。









 次に前回少し書きましたが正規表現を使ってもバージョンを取得することができます。バージョン部分は以下の文字の組み合わせで構成されています。

数値.数値
数値.数値 数値

 これは4.0とか5.23といった具合になります。つまりuserAgentの文字列の中から、このパターンを抽出すればバージョンを取得できることになります。しかし、userAgentの文字列をよく見ると先頭部分にMozilla/4.0という文字があり、この4.0も上記パターンと同じです。そこでバージョン部分を示す数値の前に半角空白があるのを利用して「半角空白ではじまり数値.数値」または「半角空白ではじまり数値.数値数値」の組み合わせをバージョン番号とします。
 正規表現では半角空白は\ で表現します。円記号の後に半角空白を入れます。数値は0〜9になるので[0-9]と表現します。.(ピリオド)は\.のように円記号の後に.(ピリオド)を書きます。数値が1個以上続く場合は+を付けます。
 正規表現でマッチした場合に結果は配列で返されます。一番最初の配列に入っている値がバージョンになりますのでeval()かparseFloat()を使って数値に変換します。
 実際のプログラムは以下のようになります。








MacOS XのブラウザSafariのバージョンを判別(1)」

 今回はMacOS XのブラウザSafariのバージョンを判別するプログラムを作成します。
 SafariMacOS Xでの標準ブラウザになるのですが、他のブラウザと比べてやっかいな状態になっています。多くの場合に判別するブラウザは

Internet Explorer
Netscape Navigator

ですが、ここにSafariが入ってくる事になります。Safariがやっかいなのは以下のuserAgentの文字列を見てみると分かります。

MacOS X 10.2のもの
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ja-jp) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.6

MacOS X 10.3のもの
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ja-jp) AppleWebKit/103u (KHTML, like Gecko) Safari/100.1

 実際にはSafari/85だったり細かいバージョンがいくつか存在します。困るのはGeckoという文字が入っている事です。なぜ困るかと言うと、この文字がGeckoエンジンを利用したブラウザ、代表的なものとしてはNetscape 6以降、Mozillaなどがあります。これらは同じエンジンを利用しているので、ほぼ同じようにレイアウトされます。(HTML,CSSなどの解釈が同じ)
 Netscape 6以降かどうかは、このGeckoの文字列で判別する事が多いため、間違ってSafariNetscapeと判別されてしまいます。このため、ブラウザを判別する場合には

(1) Safari
(2) Netscape

 の順番で処理しなければなりません。この順番でブラウザを判別したらSafariのバージョンを抜き出す作業に入ります。
 Safariの場合にはuserAgent以外にもappVersionにバージョンが表記されています。

5.0 (Macintosh; U; PPC Mac OS X; ja-jp) AppleWebKit/103u (KHTML, like Gecko) Safari/100.1

 文字列の最後の/以降がバージョンになります。と書きたい所なのですが、Safariのバージョンは


MacOS X 10.2のもの(v85.x)がバージョン1.0
MacOS X 10.3のもの(v100.x)がバージョン1.1

 となっています。つまりuserAgentに書かれているバージョンと名目上のバージョンが異なっているのです。どこから、どの範囲がどのバージョンになるのかはApple Computer次第という何とも困った状態になっています。
 今回はuserAgent内のバージョン(v85やv100)のみを抜き出してみることにします。
 文字列の最後からみて/がある次の文字列以降がバージョンになるのでlastIndexOf()を使って文字列の最後から検索を行います。/の次の文字から一番最後までを抜き出します。最後の位置は文字列の長さになりますのでlengthを使って取得することができます。実際のプログラムは以下のようになります。









 また、split()を使って判別すると非常に簡単になります。これは以下のようになります。







MacOS XのブラウザSafariのバージョンを判別(2)」

 今回はMacOS XのブラウザSafariのバージョンを判別するプログラムで1.0や1.1を返すプログラムを作成します。
 Safariが返すuserAgentの文字列をもう一度見てみましょう。

MacOS X 10.2のもの
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ja-jp) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.6

MacOS X 10.3のもの
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ja-jp) AppleWebKit/103u (KHTML, like Gecko) Safari/100.1

 前回は、この文字列の最後の部分を抜き出し表示しました。しかし、名目上のバージョンはv85.xが1.0、v100.xが1.1となっています。今回は、このような1.0、1.1のバージョンにして返すプログラムを作成します。
 一番簡単なものとしてはバージョンを抜き出して

100未満だったらバージョン1.0
86以上だったらバージョン1.1

 をif命令を使って判別することです。Safariの場合には、とにかく次のバージョンが出てみないと分からないというのが難点です。このif命令を使ったプログラムが以下のものになります。









 このプログラムだとSafariのバージョンが上がるたびにif命令で、どの範囲が、どのバージョンなのかを調べなければなりません。そこで配列(連想配列/ハッシュ)を使ってバージョンをチェックする事にします。JavaScriptでは配列の添え字([ ]の中の数値、値)にキーワード/文字列を指定することができます。これを利用し、この部分にSafariのv85やv100の文字列を割り当てます。そこに名目上のバージョンを入れておくことで、バージョンが上がっても配列を増やすだけで済みます。
 実際のプログラムは以下のようになります。








 もし、既存のバージョンでない場合にはundefinedになります。サンプルでは文字列で返していますが、数値で返しても問題ありません。処理上やりやすいものにすれば良いでしょう。

Netscape Navigatorのバージョンを判別」

 今回はNetscape Navigatorのバージョンを判別するプログラムを作成します。
 Netscape Navigatorが返すappName、appVersion、userAgentの文字列をもう一度見てみましょう。

Netscape 4.x
navigator.appName : Netscape
navigator.appVersion : 4.7 [ja] (Macintosh; U; PPC)
navigator.userAgent : Mozilla/4.7 [ja] (Macintosh; U; PPC)


Netscape 6.x
navigator.appName : Netscape
navigator.appVersion : 5.0 (Macintosh; en-US)
navigator.userAgent : Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-US; rv:0.9.4.1) Gecko/20020315 Netscape6/6.2.2


Netscape 7.x
navigator.appName : Netscape
navigator.appVersion : 5.0 (Macintosh; ja-JP)
navigator.userAgent : Mozilla/5.0 (Macintosh; U; PPC Mac OS X; ja-JP; rv:1.0.2) Gecko/20021120 Netscape/7.01


 Netscapeはバージョン5がないのですが、userAgentの文字列およびappVersionの文字列には5.0とあります。このため、バージョン4.xまでは、そのままのバージョンが使えますが、バージョン6以降ではuserAgent内の末尾の文字列に書かれているバージョンを取得しなければなりません。
 まず、appVersionの最初の1文字を取得し4以上の場合と、そうでない場合に分けます。バージョンが4以下の場合にはappVersionの最初の数値を取り出します。これは半角空白で区切られているのでsplit(" ")として取り出すことができます。バージョン6以降の場合は/で区切られているのでsplit("/")としてuserAgentから抜き出します。
 実際のプログラムは以下のようになります。