そもそも「OSを判定する」とは?
ウェブサイトを見ている人がWindows・Mac・iPhone・Androidのどれを使っているかを、ブラウザを通して調べることです。たとえば「iPhoneユーザーにだけApp Storeのリンクを見せたい」といった場面で使います。
ブラウザは自分の情報を持っている
ブラウザには navigator(ナビゲーター)という”自己紹介カード”のようなものが用意されていて、ここから端末の情報を取り出せます。JavaScriptでは navigator.〜 と書くだけでアクセスできます。
console.log(navigator.userAgent);
// 例: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."この userAgent(ユーザーエージェント)という文字列の中に、OSの名前が含まれています。先ほどのコードは、この文字列の中から「Windows」「Mac」「iPhone」などの単語を探していたのです。
コードの中で出てきた記号の意味
前回のコードに出てきた、初心者には見慣れない記号を解説します。
/Windows NT/i — スラッシュで囲まれた部分は「正規表現(せいきひょうげん)」と呼ばれるもので、文字列のパターン検索に使います。最後の i は「大文字小文字を区別しない」という意味です。「Windows NT という文字が含まれているか?」をチェックしています。
.test(userAgent) — 上のパターンを使って「userAgentの中にこの文字があるか?」を調べるメソッドです。あれば true、なければ false を返します。
if (〜) return '〜' — 「もし〜なら、〜という結果を返す」という条件分岐です。上から順番にチェックして、最初に当てはまったOS名を返しています。
つまり前回のコードは、「自己紹介カードの文字列を読んで、含まれる単語からOS名を判定する」というシンプルな仕組みなのです。
なぜiPadだけ特別扱い?
最近のiPadは「自分はMacです」とウソをつくようになりました(パソコン向けのサイトを表示するため)。なのでMacと判定された場合でも、navigator.maxTouchPoints(同時にタッチできる指の本数)が2本以上ならiPadだと判断する、というひと工夫が必要になります。Macのトラックパッドはこの値が0なので区別できるわけです。
3つの方法の使い分け
JavaScriptで端末のOSを判定する主な方法を3つ紹介します。
方法1: navigator.userAgentを使う(最も一般的)
function getOS() {
const userAgent = navigator.userAgent;
if (/Windows NT/i.test(userAgent)) return 'Windows';
if (/Mac OS X/i.test(userAgent) && !/Mobile/i.test(userAgent)) return 'macOS';
if (/Android/i.test(userAgent)) return 'Android';
if (/iPhone|iPad|iPod/i.test(userAgent)) return 'iOS';
if (/Linux/i.test(userAgent)) return 'Linux';
return 'Unknown';
}
console.log(getOS());注意点として、最近のiPadは初期設定でmacOSと同じUser-Agentを返すため、タッチ判定で補正することが多いです。
function getOSDetailed() {
const ua = navigator.userAgent;
// iPadOS 13以降の判定(macOSと区別するためにタッチ機能を確認)
if (/Mac/i.test(ua) && navigator.maxTouchPoints > 1) return 'iPadOS';
if (/iPhone|iPad|iPod/i.test(ua)) return 'iOS';
if (/Android/i.test(ua)) return 'Android';
if (/Windows/i.test(ua)) return 'Windows';
if (/Mac/i.test(ua)) return 'macOS';
if (/Linux/i.test(ua)) return 'Linux';
return 'Unknown';
} navigator.userAgent が現在もっとも広く使われている方法で、すべてのブラウザで動きます。迷ったらこれです。
方法2: navigator.userAgentDataを使う(モダンな方法)
Chrome系ブラウザで使える新しいAPIです。User-Agent文字列より構造化されていて扱いやすいですが、Safari/Firefoxではまだ未対応です。
async function getOSModern() {
if (navigator.userAgentData) {
// 高エントロピー値も取得可能
const data = await navigator.userAgentData.getHighEntropyValues(['platform', 'platformVersion']);
return `${data.platform} ${data.platformVersion}`;
}
// フォールバック
return navigator.userAgent;
}navigator.userAgentData は新しく作られた方法で、より整理された情報が取れますが、Safari(iPhoneのブラウザ)などではまだ使えません。
方法3: navigator.platformを使う(非推奨)
シンプルですが、現在は非推奨APIです。
navigator.platform は昔からある簡単な方法ですが、「もう新しく使わないでね」と公式に言われている古い機能なので、今から学ぶ方はあまり気にしなくて大丈夫です。
console.log(navigator.platform); // "Win32", "MacIntel", "Linux x86_64" など実用上のアドバイス
User-Agentは偽装可能で、ブラウザによっては正確な情報を返さないため、OSの判定はUIの最適化など軽い用途に留めるのがおすすめです。重要な機能の分岐には、機能検出(feature detection)を使うほうが安全です。
User-Agentは簡単に書き換えられるものなので、100%正確ではありません。「重要な処理の分岐」には使わず、見た目を少し変える程度の用途にとどめるのが安全です。
たとえば「タッチ操作できる端末か知りたい」だけなら、OSを判定するより、こう書くほうが確実です。
// 例: タッチデバイスかどうかを機能で判定
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0;これは「このブラウザはタッチイベントに対応しているか?」を直接調べる方法で、OS判定よりも信頼できます。OSを聞くより、できることを聞いたほうが正確、という考え方ですね。