Safariブラウザを検出する


142

JavaScriptを使用してSafariブラウザを検出する方法は?以下のコードを試したところ、SafariだけでなくChromeブラウザも検出されました。

function IsSafari() {

  var is_safari = navigator.userAgent.toLowerCase().indexOf('safari/') > -1;
  return is_safari;

}

1
ファイル送信に関連するJSコードの一部は、Safariで遅延的に機能します。Chromeは正常に機能します。
トーマス、

1
ほぼ間違いなく、APIの違いをテストする必要があります。SafariとChrome以外にも、他のWebKitベースのブラウザーがあります。
Quentin

12
ブラウザを検出したい理由はたくさんあります。たとえば、これを書いている時点では、フィルターなどのSVGエンジンの特定の側面はSafariでは機能しませんが、Chromeでは機能します。
Paul Legato

再現できないため、バグを修正できない場合があります(Macにアクセスできません)。Midoriの問題(sendAsBinaryシムのBlobBuilder / Blobの問題)を修正しましたが、クライアントはファイルのアップロードにまだ問題があると言っています。古いIE)
llamerr 2013年

回答:


110

Chromeのインデックスを簡単に使用して、Chromeを除外できます。

var ua = navigator.userAgent.toLowerCase(); 
if (ua.indexOf('safari') != -1) { 
  if (ua.indexOf('chrome') > -1) {
    alert("1") // Chrome
  } else {
    alert("2") // Safari
  }
}

6
動作しません。現在iPhoneでchrome UA文字列を出力しており、「chrome」という単語すら含まれていません。
ポールカールトン

5
Windows 10のIE 11 UA文字列にはSafariとChromeも含まれています
2015

Blackberryには「Safari」も含まれています。
ハリーペコネン2015年

18
@Flimmブラウザー検出には多くの正当な使用例があります。質問者または回答者の意図を知っていると思い込まないでください。関連があると思われるかもしれない役立つヒントを含めることは素晴らしいことですが、それは決して要件ではありません。
ルーベンマルティネスジュニア

1
:これは、「サファリ」ではなく「クローム」が含まれるAndroidのブラウザでの作業、ないdevelopers.whatismybrowser.com/useragents/explore/software_name/...を
エリック・アンドリュー・ルイス

156

注:次のようにターゲットを設定するのではなく、修正しようとしている特定の動作を常に検出するようにしてくださいisSafari?

最後の手段として、次の正規表現でSafariを検出します。

var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);

ネガティブルックアラウンドを使用Safariし、ユーザーエージェントに名前を含むChrome、Edge、およびすべてのAndroidブラウザーを除外します。


2
これは機能しません。iPhoneでChromeブラウザを使用している場合でも、私はまだ本当です。
ayjay

27
これは、Chromeを含め、iOS上のすべてのブラウザがSafari(MiniモードのOpera Miniを除く)のラッパーにすぎないためです。これは、userAgent文字列がラッパーに対応しているため、これらすべてがこのテストに一致することを必ずしも意味しません。iOSでChromeを個別に検出することができます。
fregante

これは私のために働いた男!!! おかげで。navigator.userAgentは、WindowsのChromeとMacのSafariの両方で「5.0(Windows NT 6.1)AppleWebKit / 537.36(KHTML、like Gecko)Chrome / 39.0.2171.99 Safari / 537.36」のような値を返していました。
KaustubhSV 2015

2
今修正されました。間違いなく、多くのブラウザの問題は、除外されないように他の名前が含まれていることです。Like EdgeのUAにはChromeとSafariの両方が含まれています。ユーザーエージェントのチェックは、この理由により不適切です。ブラウザが変更され、チェックを更新する必要があります。残念ながら、ブラウザを検出する完璧な方法はありません。それは常に推測です。
fregante 2015年

1
機能検出を使用することは間違いなく良いアイデアですが、たとえばモバイルのビデオが自動的にフルスクリーンになるか、iPhoneとiPodでのみ発生するかなど、一部の動作はテストするのが難しいかほぼ不可能です。それをテストするには、ビデオをロードしてユーザーに再生させる必要があります。
fregante 2015

91

他の人々がすでに述べたように、特定のブラウザをチェックするよりも機能検出が優先されます。1つの理由は、ユーザーエージェント文字列が変更される可能性があることです。別の理由は、新しいバージョンでは文字列が変更されてコードが壊れる可能性があるためです。

それでもそれを実行してSafariのバージョンをテストする場合は、これを使用することをお勧めします

var isSafari = navigator.vendor && navigator.vendor.indexOf('Apple') > -1 &&
               navigator.userAgent &&
               navigator.userAgent.indexOf('CriOS') == -1 &&
               navigator.userAgent.indexOf('FxiOS') == -1;

これは、すべてのデバイス(Mac、iPhone、iPod、iPad)のすべてのバージョンのSafariで動作します。

編集する

現在のブラウザでテストするには: https //jsfiddle.net/j5hgcbm2/

編集2

Chromeのドキュメントに従って更新、iOSでChromeを正しく検出するようになりました

iOS上のすべてのブラウザーはSafariのラッパーにすぎず、同じエンジンを使用することに注意してください。このスレッドで彼自身の答えについてのbfred.itのコメントを参照してください。

編集3

Firefoxのドキュメントに従って更新され、iOS上のFirefoxを正しく検出します


コメントをありがとう
-iOSで

@qingu-このjavascriptが理解できません。どのようにすればよいですか-if(safaribrowser){do this} else {do}同じコードを使用して、値が 'var isSafari'であるおかげで
GAV

@GAVは:isSafariとなりtrue、Safariブラウザでfalseそう。上記のスニペットを使用して、投稿したとおりに使用できます。if (isSafari) { do_this(); } else { do_that(); }
qingu

2
残念ながら、機能検出だけでなく、ブラウザを理解しようとする理由は他にもあります。ブラウザは機能をサポートできますが、バグがあります(例:IE10ではキャンバスのバグですが、IE9では同じ機能が動作します)。また、Firefoxの動作は、マウスの動きに対する応答など、Webkitベースのブラウザーとは異なります。AppleのSafariには、Chromeにはないリフローのバグがあります。一部のブラウザは、特定の計算負荷の高いタスクを他のブラウザよりも実行するとパフォーマンスが向上します。
DemiImp 2016年

2
@Andras Firefoxの場合&& !navigator.userAgent.match('FxiOS')、Chromeチェックと同様に追加できます-ref (developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/…
Petri Pellinen

60

ただ使用する:

var isSafari = window.safari !== undefined;
if (isSafari) console.log("Safari, yeah!");

15
なぜこれが上に上がらないのかわからない-これは完璧で、短く、簡単なことなのか。デスクトップサファリの不足を排除する必要がありましたgetUserMedia
Stephen Tetreault 2017

3
これはモバイルでは機能しないため、デスクトップサファリを決定するのに最適な方法です
godblessstrawberry '16年

これはどのバージョンのSafariで機能しますか?v5.1.7で動作しないようです
ElliotSchmelliot 2018

ブラウザだけに関心があり、モバイルとデスクトップのどちらにも関心がない場合、これは完全に機能します。
アントゥアン

1
これはiPhone 11 Pro Max Simulator 13.5内では機能しませんでした
クリスチャンバレンティン

19

このコードはSafariブラウザのみを検出するために使用されます

if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) 
{
   alert("Browser is Safari");          
}

4
このコードは、WebkitブラウザーがChromeではないかどうかを検出するだけです。他の多くのブラウザは、ユーザーエージェント文字列に「safari」を含めるという悪い考えを持っています。たとえば、Opera Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36 OPR/24.0.1558.51 (Edition Next)Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24
:、

トスティングプラットフォームの検出により、特定の互換性ケースが除外される可能性があります。
ljgww

私はちょうど半ダースのサードパーティiOSブラウザーをチェックしました、それらはすべて非常に正確なSafariユーザーエージェントを偽装しています。
ミッチマッチ

したがって、これはChromeのみを検出します。それでも、Chrome 44のUAにはChromeがなくなっていることがわかりましたが、代わりに「CriOS」:(
Mitch Match

機能の検出を常に試みて、最後の手段としてブラウザーの検出を使用する必要があります。後者の方法は、正当なユーザーを破壊してブロックする可能性がはるかに高いためです。機能検出についてまったく触れていない答えは、私から反対票を得ています。
Flimm 2017年

12

ChromeとSafariのuserAgentはほぼ同じであるため、ブラウザーのベンダーを確認する方が簡単です。

サファリ

navigator.vendor ==  "Apple Computer, Inc."

クロム

navigator.vendor ==  "Google Inc."

FireFox(なぜそれが空なのですか?)

navigator.vendor ==  ""

IE(なぜ未定義なのですか?)

navigator.vendor ==  undefined

1
さまざまなコンピューター(Macデスクトップ、iPadなど)で動作するSafariで警告メッセージを無効にするための何かを探していましたが、これは完全に機能しました。
dylnmc 2017年

ただし、iOS上のChromeのベンダーも「Apple Computer、Inc.」になります。申し訳ありません...
Piotr Kowalski

@PiotrKowalski-どのソリューションを使いましたか?
タイラーリンデル、

@tylerlindellこのページの下部にある「バージョン」という単語を使った私の回答を参照してください。
Piotr Kowalski

7

サファリのみ whitout Chrome:

他のコードを試した後、Safariの新旧バージョンで動作するコードは見つかりませんでした。

最後に、私にとって非常にうまく機能するこのコードを実行しました。

var ua = navigator.userAgent.toLowerCase(); 
var isSafari = false;
try {
  isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || safari.pushNotification);
}
catch(err) {}
isSafari = (isSafari || ((ua.indexOf('safari') != -1)&& (!(ua.indexOf('chrome')!= -1) && (ua.indexOf('version/')!= -1))));

//test
if (isSafari)
{
  //Code for Safari Browser (Desktop and Mobile)
  document.getElementById('idbody').innerHTML = "This is Safari!";
}
else
{
  document.getElementById('idbody').innerHTML = "Not is Safari!";
}
<body id="idbody">
</body>


5

Safariを区別する単語は1つだけです-"バージョン"。したがって、この正規表現は完璧に機能します。

/.*Version.*Safari.*/.test(navigator.userAgent)

5

OPがSafariを検出したかった理由はわかりませんが、まれなケースですが、今日ではブラウザーの名前よりもレンダリングエンジンを検出するほうが重要な場合があります。たとえばiOSでは、すべてのブラウザーがSafari / Webkitエンジンを使用しているため、基盤となるレンダラーが実際にSafari / Webkitである場合、ブラウザー名として「chrome」または「firefox」を取得しても意味がありません。私はこのコードを古いブラウザでテストしていませんが、Android、iOS、OS X、Windows、Linuxでごく最近のすべてで動作します。

<script>
    let browserName = "";

    if(navigator.vendor.match(/google/i)) {
        browserName = 'chrome/blink';
    }
    else if(navigator.vendor.match(/apple/i)) {
        browserName = 'safari/webkit';
    }
    else if(navigator.userAgent.match(/firefox\//i)) {
        browserName = 'firefox/gecko';
    }
    else if(navigator.userAgent.match(/edge\//i)) {
        browserName = 'edge/edgehtml';
    }
    else if(navigator.userAgent.match(/trident\//i)) {
        browserName = 'ie/trident';
    }
    else
    {
        browserName = navigator.userAgent + "\n" + navigator.vendor;
    }
    alert(browserName);
</script>

明確にするために:

  • iOSでのすべてのブラウザは「safari / webkit」として報告されます
  • Androidを除くすべてのブラウザ、Firefoxは「chrome / blink」として報告されます
  • Chrome、Opera、Blisk、Vivaldiなどはすべて、Windows、OS XまたはLinuxで「chrome / blink」として報告されます

4

私はこれを使います

function getBrowserName() {
    var name = "Unknown";
    if(navigator.userAgent.indexOf("MSIE")!=-1){
        name = "MSIE";
    }
    else if(navigator.userAgent.indexOf("Firefox")!=-1){
        name = "Firefox";
    }
    else if(navigator.userAgent.indexOf("Opera")!=-1){
        name = "Opera";
    }
    else if(navigator.userAgent.indexOf("Chrome") != -1){
        name = "Chrome";
    }
    else if(navigator.userAgent.indexOf("Safari")!=-1){
        name = "Safari";
    }
    return name;   
}

if( getBrowserName() == "Safari" ){
    alert("You are using Safari");
}else{
    alert("You are surfing on " + getBrowserName(name));
}

4

最も簡単な答え:

function isSafari() {
 if (navigator.vendor.match(/[Aa]+pple/g).length > 0 ) 
   return true; 
 return false;
}

2
これは機能しますが、正規表現なしでより簡単に実行できます:navigator.vendor.toLowerCase().indexOf('apple') > -1
fviktor

5
さらに簡単... if (navigator.vendor.match(/apple/i)) { ... }
ブラッド

これはApple Computer、Incを示しているため、Firefox上の
iOS

1
@nuttynibbles:iOSのすべてのブラウザーがSafariを偽装しているため、おそらくこれが必要です。
ワートワート

3

記録として、私が見つけた最も安全な方法は、この回答からのブラウザー検出コードのSafari部分を実装することです。

const isSafari = window['safari'] && safari.pushNotification &&
    safari.pushNotification.toString() === '[object SafariRemoteNotification]';

もちろん、ブラウザ固有の問題に対処する最良の方法は、可能であれば、常に機能検出を行うことです。ただし、上記のようなコードを使用する方が、エージェント文字列の検出よりも優れています。


1
これは、iPhone OS 13_4_1上のsafariバージョン/13.1 Mobile / 15E148 Safari / 604.1では機能しません。
mindo

2

私はこの質問が古いことを知っていますが、誰かに役立つかもしれないので、とにかく答えを投稿することを考えました。上記のソリューションは一部のエッジケースで失敗するため、iOS、デスクトップ、およびその他のプラットフォームを個別に処理する方法で実装する必要がありました。

function isSafari() {
    var ua = window.navigator.userAgent;
    var iOS = !!ua.match(/iP(ad|od|hone)/i);
    var hasSafariInUa = !!ua.match(/Safari/i);
    var noOtherBrowsersInUa = !ua.match(/Chrome|CriOS|OPiOS|mercury|FxiOS|Firefox/i)
    var result = false;
    if(iOS) { //detecting Safari in IOS mobile browsers
        var webkit = !!ua.match(/WebKit/i);
        result = webkit && hasSafariInUa && noOtherBrowsersInUa
    } else if(window.safari !== undefined){ //detecting Safari in Desktop Browsers
        result = true;
    } else { // detecting Safari in other platforms
        result = hasSafariInUa && noOtherBrowsersInUa
    }
    return result;
}


1

このユニークな「問題」は、ブラウザがSafariであるという100%の兆候です(信じられないかもしれませんが)。

if (Object.getOwnPropertyDescriptor(Document.prototype, 'cookie').descriptor === false) {
   console.log('Hello Safari!');
}

これは、Safariではcookieオブジェクト記述子がfalseに設定されているが、他のすべてではtrueであることを意味します。これにより、実際には他のプロジェクトで頭痛の種となっています。幸せなコーディング!


もう真実ではないようです。Firefoxでもクラッシュ "Object.getOwnPropertyDescriptor(...)is undefined"
Offirmo

0

多分これはうまくいきます:

Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor')

編集:機能しない


すべてのブラウザで-1を返すため、これは正確に何をしているのでしょうか?
ペトロフ2016年

@Petroff新しいサファリでは動作しなくなりました。指摘してくれてありがとう。
Harshal Carpenter

2
答えは自由に削除してください。
Flimm 2018

0

ブール型を返す関数を作成します。

export const isSafari = () => navigator.userAgent.toLowerCase().indexOf('safari') !== -1

-2

ユーザーエージェントのスニッフィングは本当にトリッキーで信頼性が低くなります。上記の@qinguの回答のようなものを使用してiOSでSafariを検出しようとしましたが、Safari、Chrome、Firefoxでうまく機能しました。しかし、それはOperaとEdgeをSafariとして誤って検出しました。

そのため、今日のように機能検出が行われましたが、これserviceWorkerはSafariでのみサポートされており、iOSの他のブラウザーではサポートされていません。https://jakearchibald.github.io/isserviceworkerready/で述べられているように

サポートには、そのプラットフォーム上のサードパーティ製ブラウザーのiOSバージョンは含まれません(Safariサポートを参照)。

だから私たちは次のようなことをしました

if ('serviceWorker' in navigator) {
    return 'Safari';
}
else {
    return 'Other Browser';
}

:MacOSのSafariではテストされていません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.