Safari 브라우저 감지


142

JavaScript를 사용하여 Safari 브라우저를 감지하는 방법? 아래 코드를 시도했는데 Safari뿐만 아니라 Chrome 브라우저도 감지합니다.

function IsSafari() {

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

}

1
파일 제출과 관련된 일부 JS 코드는 Safari에서 제대로 작동하지 않으므로 Chrome이 제대로 작동합니다.
Tomas

1
API의 차이점에 대해 거의 확실하게 테스트해야합니다. Safari 및 Chrome 이외의 다른 WebKit 기반 브라우저가 있습니다.
Quentin

12
브라우저를 감지하는 데는 여러 가지 이유가 있습니다. 예를 들어,이 글을 쓰는 시점에서 필터와 같은 SVG 엔진의 특정 측면은 Safari에서 손상되었지만 Chrome에서는 작동합니다.
Paul Legato

때로는 재현 할 수 없기 때문에 버그를 해결할 수없는 경우가 있습니다 (Mac에 액세스 할 수 없음). Midori (sendAsBinary shim의 일부 BlobBuilder / Blob 문제)에서 문제를 해결했지만 클라이언트가 파일 업로드에 여전히 문제가 있다고 말하면서 가장 좋은 것은 Safari 지원을 제거하고 iframe을 사용하는 것입니다. old IE)
llamerr

답변:


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"이라는 단어조차 없습니다.
Paul Carlton

5
Windows 10의 IE 11 UA 문자열에는 Safari와 Chrome도 포함되어 있습니다.
cuixiping

블랙 베리에는 "Safari"도 포함됩니다.
Harry Pehkonen

18
@Flimm 브라우저 감지에는 합법적 인 사용 사례가 많이 있습니다. 응답자 또는 응답자의 의도를 알고 있다고 가정하지 마십시오. 관련성이 있다고 생각되는 유용한 팁을 포함하는 것이 좋지만 결코 요구 사항은 아닙니다.
Ruben Martinez Jr.

1
"safari"는 포함하지만 "chrome"은 포함하지 않는 Android 브라우저에서는 작동하지 않습니다. developers.whatismybrowser.com/useragents/explore/software_name/…
Eric Andrew Lewis

156

참고 : 수정하려는 특정 행동을 항상 타겟팅하지 말고 감지하십시오.isSafari?

최후의 수단 으로이 정규식으로 Safari를 감지하십시오.

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

부정적인 둘러보기를 사용하며 Chrome, Edge 및 Safari사용자 에이전트에 이름 을 포함하는 모든 Android 브라우저를 제외합니다 .


2
작동하지 않습니다. iPhone에서 Chrome 브라우저를 사용하는 경우에도 여전히 사실입니다.
ayjay

27
iOS의 모든 브라우저는 Chrome을 포함하여 Safari의 미니 래퍼 ( 미니 모드 의 Opera Mini 제외 )이기 때문입니다. 이것은 userAgent 문자열이 랩퍼에 있으므로이 테스트와 모두 일치 한다는 의미는 아닙니다 . iOS에서 Chrome을 별도로 감지 할 수 있습니다 .
fregante

야이게 나를 위해 일했다 !!! 감사합니다. navigator.userAgent는 Windows의 Chrome과 mac의 Safari 모두에 대해 "5.0 (Windows NT 6.1) AppleWebKit / 537.36 (Kcko, Gecko) Chrome / 39.0.2171.99 Safari / 537.36"과 같은 값을 반환했습니다.
KaustubhSV

2
지금 수정했습니다. 당신은 확실히 맞습니다. 많은 브라우저의 문제는 다른 이름을 포함하여 제외시키지 않으려는 것입니다. Like Edge는 UA에 Chrome과 Safari를 모두 포함합니다. 이러한 이유로 사용자 에이전트 확인이 잘못되었습니다. 브라우저가 변경되고 확인이 업데이트되어야합니다. 불행히도 브라우저를 감지하는 완벽한 방법은 없지만 항상 추측입니다.
fregante

1
확실히 기능 감지를 사용하는 것이 좋지만 일부 동작은 테스트하기 어렵거나 거의 불가능합니다. 예를 들어 모바일의 비디오가 자동으로 전체 화면으로 이동하는지 여부는 iPhone 및 iPod에서만 발생합니다. 비디오를 테스트하려면 비디오를로드하고 사용자가 비디오를 재생하도록해야합니다.
fregante

91

다른 사람들이 이미 언급했듯이 기능 검색은 특정 브라우저를 확인하는 것보다 선호됩니다. 한 가지 이유는 사용자 에이전트 문자열을 변경할 수 있기 때문입니다. 또 다른 이유는 문자열이 최신 버전에서 코드를 변경하고 중단시킬 수 있기 때문입니다.

그래도 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 문서 에 따라 업데이트되었습니다.

iOS의 모든 브라우저는 Safari의 래퍼 일 뿐이며 동일한 엔진을 사용한다는 점은 주목할 가치가 있습니다. 이 글에서 자신의 답변에 대한 bfred.it의 의견을 참조하십시오.

편집 3

iOS에서 Firefox를 올바르게 감지 하도록 Firefox 문서 에 따라 업데이트되었습니다.


댓글 주셔서 감사합니다-iOS에서 Chrome을 올바르게 감지하도록 업데이트
qingu

@qingu -이 자바 스크립트를 이해하지 못하고, 어떻게 같은 것을 할 것 - 만약 (safaribrowser를) 다른 {이렇게} 'VAR isSafari'덕분에 어떤 값을 동일한 코드이다 사용하여 {그렇게}
게이트웨이 AV

@GAV는 : isSafaritrue, 사파리 브라우저에서 false그렇지. 위의 스 니펫을 사용하고 게시 한 그대로 사용할 수 있습니다. if (isSafari) { do_this(); } else { do_that(); }.
qingu

2
불행히도 단순히 기능 감지보다 브라우저를 파악해야하는 더 많은 이유가 있습니다. 브라우저는 기능을 지원할 수 있지만 버그가 있습니다 (예 : IE10에서는 캔버스 버그이지만 IE9에서는 동일한 기능이 작동합니다). 또한 Firefox는 마우스 움직임에 반응하는 방식과 같이 웹킷 기반 브라우저와 다르게 작동합니다. Apple의 Safari에는 Chrome에는없는 리플 로우 버그가 있습니다. 일부 브라우저는 다른 브라우저보다 계산 집약적 인 특정 작업을 수행 할 때 성능이 뛰어납니다.
DemiImp

2
@Andras Firefox의 && !navigator.userAgent.match('FxiOS')경우 Chrome check-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 2016

3
이것은 모바일에서 작동하지
않기

어떤 Safari 버전에서 작동합니까? v5.1.7에서 작동하지 않는 것
ElliotSchmelliot

모바일과 데스크톱이 아닌 브라우저 만 신경 쓰면 완벽하게 작동합니다.
Antuan

1
이것은 iPhone 11 Pro Max Simulator 13.5-7
Christian Valentin

19

이 코드는 사파리 브라우저 만 감지하는 데 사용됩니다

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

4
이 코드는 웹킷 브라우저가 크롬이 아닌 것을 감지합니다. 다른 많은 브라우저는 사용자 에이전트 문자열에 "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)또는 Stock Android 브라우저 :Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24
rupps

던지기 플랫폼 탐지는 특정 호환성 사례를 필터링 할 수 있습니다.
ljgww

방금 써드 파티 (third party) iOS 브라우저를 확인했는데, 모두 매우 정확한 Safari User-Agent를 속입니다.
Mitch Match

따라서 이것은 Chrome 만 감지합니다. 그러나 방금 Chrome 44가 더 이상 UA에 Chrome을 가지고 있지 않다는 것을 알았습니다. 대신 'CriOS':(
Mitch Match

우리는 항상 기능 탐지를 시도하고 브라우저 탐지를 최후의 수단으로 사용해야합니다. 후자는 합법적 인 사용자를 차단하고 차단할 가능성이 훨씬 높기 때문입니다. 기능 감지를 전혀 언급하지 않은 답변은 저에게서 공감대를 받고 있습니다.
Flimm

12

chrome 및 safari 용 userAgent가 거의 동일하므로 브라우저 공급 업체를보다 쉽게 ​​확인할 수 있습니다.

원정 여행

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

크롬

navigator.vendor ==  "Google Inc."

FireFox (비어있는 이유는 무엇입니까?)

navigator.vendor ==  ""

IE (왜 정의되지 않습니까?)

navigator.vendor ==  undefined

1
다양한 컴퓨터 (Mac 데스크탑, ipad 등)에서 사파리에서 경고 메시지를 비활성화 할 무언가를 찾고 있었는데 완벽하게 작동했습니다.
dylnmc 2016 년

그러나 iOS의 Chrome 공급 업체는 "Apple Computer, Inc."도됩니다. 미안 ...
Piotr Kowalski

@PiotrKowalski-어떤 솔루션을 사용하셨습니까?
tylerlindell

@tylerlindell이 페이지 하단에서 "version"단어로 답을 확인하십시오.
Piotr Kowalski

7

사파리 whitout 크롬 만 :

다른 코드를 시도한 후에 새롭고 오래된 버전의 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

사파리를 구별하는 단어는 "버전"입니다. 따라서이 정규식은 완벽하게 작동합니다.

/.*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)) { ... }.
Brad

Firefox
iOS

1
@nuttynibbles : iOS의 모든 브라우저가 변장 된 사파리이기 때문에 이것은 아마도 당신이 원하는 것입니다.
wortwart

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

위의 답변에 대한 수정 된 정규식

var isSafari = /^((?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent);
  • 크리 오스-크롬
  • fxios-Firefox

1

이 독특한 "문제"는 브라우저가 Safari라는 것을 100 % 표시합니다 (믿거 나 말거나).

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

이것은 쿠키 객체 디스크립터가 Safari에서 false로 설정되어 있고 다른 모든 쿠키가 true이므로 실제로 다른 프로젝트에서 두통을 유발한다는 것을 의미합니다. 행복한 코딩!


더 이상 사실이 아닌 것 같습니다. Firefox에서 충돌이 발생 함 "Object.getOwnPropertyDescriptor (...) is undefined"
Offirmo

0

어쩌면 이것은 작동합니다 :

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

편집 : 더 이상 작동하지 않음


모든 브라우저에서 -1을 반환하기 때문에 정확히 어떻게해야합니까?
Petroff

@Petroff 더 이상 새로운 사파리에서 작동하지 않습니다. 지적 해 주셔서 감사합니다.
Harshal Carpenter

2
답변을 자유롭게 삭제하십시오.
Flimm

0

부울 형식을 반환하는 함수를 만듭니다.

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

-2

사용자 에이전트 스니핑은 정말 까다 롭고 신뢰할 수 없습니다. 위의 @qingu의 답변과 같은 iOS에서 Safari를 감지하려고 시도했지만 Safari, Chrome 및 Firefox에서 잘 작동했습니다. 그러나 Opera와 Edge를 Safari로 잘못 감지했습니다.

그래서 오늘과 같이 기능 감지 기능을 사용했습니다 serviceWorker.iOS의 다른 브라우저에서는 지원되지 않고 Safari에서만 지원됩니다. 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.