web-dev-qa-db-ja.com

Safariブラウザーを検出する

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

function IsSafari() {

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

}
107
Tomas

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

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

注:isSafari?でターゲットを設定する代わりに、修正しようとしている特定の動作を常に検出しようとします

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

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

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

118
fregante

他の人々がすでに指摘しているように、特定のブラウザのチェックよりも機能検出が好まれます。 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

IOSでChromeを正しく検出するために Chrome docs に従って更新されました

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

編集3

Firefox docs に従って更新され、iOS上のFirefoxを正しく検出する

73
qingu

使用するだけ:

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

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

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

chromeとsafariのuserAgentはほぼ同じであるため、ブラウザーのベンダーを簡単に確認できます。

サファリ

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

クローム

navigator.vendor ==  "Google Inc."

FireFox(なぜ空ですか?)

navigator.vendor ==  ""

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

navigator.vendor ==  undefined
9
tylerlindell

Safari 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
leoledmag

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));
}
3
lovepong

私はこの質問が古いことを知っていますが、誰かに役立つかもしれないので、とにかく答えを投稿することを考えました。上記のソリューションは一部のEdgeのケースでは失敗していたため、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;
}
2
H H

Safariを区別するのは「バージョン」という1つのWordだけです。したがって、この正規表現は完璧に機能します:

/.*Version.*Safari.*/.test(navigator.userAgent)
2
Piotr Kowalski

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

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

これは、SafariではCookieオブジェクト記述子がfalseに設定されているが、他のすべてではtrueに設定されていることを意味します。ハッピーコーディング!

1
zoxxx

回答の修正正規表現 上記

var isSafari = /^((?!chrome|Android|crios|fxios).)*safari/i.test(navigator.userAgent);
  • crios-Chrome
  • fxios-Firefox
1
Yurii Sherbak

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

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

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

0
Marcos Sandrini

たぶんこれは動作します:

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

編集:もはや機能しません

0