确定用户是否从移动Safari浏览


71

我有一个应用程序,我想根据用户的导航位置将其重定向到不同的页面。

如果从Web剪辑导航,请不要重定向。如果从移动Safari浏览,请重定向到safari.aspx。如果从其他任何地方导航,请重定向到unavailable.aspx

我能够使用iPhone WebApp,是否可以检测其加载方式?主屏幕还是Safari?确定用户是否正在从Web剪辑导航,但是我无法确定用户是否从iPhone或iPod上的移动Safari浏览。

这是我所拥有的:

if (window.navigator.standalone) {
    // user navigated from web clip, don't redirect
}
else if (/*logic for mobile Safari*/) {
    //user navigated from mobile Safari, redirect to safari page
    window.location = "safari.aspx";
}
else {
    //user navigated from some other browser, redirect to unavailable page
    window.location = "unavailable.aspx";
}


@Ali这个问题并不是在问这个问题
Jake Millington

Answers:


30

更新:这是一个很旧的答案,因为答案被接受,所以我不能删除它。请在下面查看不知情的答案,以获得更好的解决方案。


您应该能够在用户代理字符串中检查“ iPad”或“ iPhone”子字符串:

var userAgent = window.navigator.userAgent;

if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i)) {
   // iPad or iPhone
}
else {
   // Anything else
}

11
我认为不是。与Safari iOS浏览器有何不同?我认为这种表达方式不仅会排除Safari,而且还会排除所有iphone / ipad浏览器。
卡米留斯

16
这不是正确的答案,因为如果我从chrome中访问ios,它将返回true
Bobby Stenly 2015年

7
这是行不通的,因为用户现在可以在iOS上使用Mobile Chrome浏览器,即使它不是Mobile Safari,也仍然会返回true。
jangosteve

2
这不会检测到用户是否正在使用移动Chrome。与Safari相比,Chrome iOS具有非常古老的JavaScript引擎(由于Apple的政策),因此无法进行某些渲染。
航空王

2
不应将其标记为正确答案,因为它包括iPhone上运行的所有浏览器。这个问题专门要求检测移动safari。
Shashank

165

请参阅https://developer.chrome.com/multidevice/user-agent#chrome_for_ios_user_agent-iOS上的Safari和iOS上的Chrome的用户代理字符串不便相似:

Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3

苹果浏览器

Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543 Safari/419.3

看起来这里最好的方法是首先根据其他答案的建议检查iOS,然后过滤使Safari UA变得独一无二的内容,我建议最好使用“是AppleWebKit而不是CriOS”来完成:

var ua = window.navigator.userAgent;
var iOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i);
var webkit = !!ua.match(/WebKit/i);
var iOSSafari = iOS && webkit && !ua.match(/CriOS/i);

1
@fabricioflores c'est la vie :(

7
+1这里唯一涵盖所有规格的答案。我只是将iOS测试正则表达式更改为,/iP(ad|hone)/i因此您不需要or。
2015年

2
@sareed我总是感到非常满意,能够对iP(ad | od | hone)进行正则表达式

8
iOS上的愚蠢Opera仍会在上面的代码中传递true,因此我将最后一行更改为:var iOSSafari = iOS && webkit &&!ua.match(/ CriOS / i)&&!ua.match(/ OPiOS / i) ;
Hooman Askari 2015年

3
好答案。但是,为什么可以在使用test()时使用带有匹配项的双负(!!)?
OMA

27

最佳做法是:

function isMobileSafari() {
    return navigator.userAgent.match(/(iPod|iPhone|iPad)/) && navigator.userAgent.match(/AppleWebKit/)
}

25
这也将适用于Chrome iOS :( stackoverflow.com/a/13808053/668157
httpete 2013年

这也可以检测移动铬。
肖恩

那么,我们应该如何区分iOS Safari和iOS Chrome?有任何想法吗?
BurakKarakuş16年

这两个正则表达式可以轻松地组合在一起
antoine129 '16

这也与Desktop Safari匹配。
antoine129

7

下降的代码只能找到移动浏览器,没有别的(海豚和其他小型浏览器除外)

  (/(iPad|iPhone|iPod)/gi).test(userAgent) &&
  !(/CriOS/).test(userAgent) &&
  !(/FxiOS/).test(userAgent) &&
  !(/OPiOS/).test(userAgent) &&
  !(/mercury/).test(userAgent)

1
这是唯一将Firefox和Opera在iOS上区分开的人。
nord-stream

5

合并所有答案和评论。这就是结果。

function iOSSafari(userAgent)
{
    return /iP(ad|od|hone)/i.test(userAgent) && /WebKit/i.test(userAgent) && !(/(CriOS|FxiOS|OPiOS|mercury)/i.test(userAgent));
}



var iOSSafari = /iP(ad|od|hone)/i.test(window.navigator.userAgent) && /WebKit/i.test(window.navigator.userAgent) && !(/(CriOS|FxiOS|OPiOS|mercury)/i.test(window.navigator.userAgent));

我猜想这也符合桌面浏览器(WebKit
antoine129 '16

1
@ antoine129不,它没有(在OS X El Capitan上测试)-regexzzzz已AND,我猜Desktop Safari永远不会发送iP * ...
Christian Ulbrich

5

查看所有答案,以下是有关拟议RegExes的一些提示:

  • AppleWebKit 也与桌面Safari匹配(不仅限于移动设备)
  • .match对于这种简单的正则表达式,无需多次调用,而更喜欢使用lighter.test方法。
  • g(全局)的正则表达式标志为无用,而i(不区分大小写)可以是有用的
  • 无需捕获(括号),我们只是测试字符串

我正在使用此功能,因为true对于我来说可以使用移动Chrome浏览器(行为相同):

/iPhone|iPad|iPod/i.test(navigator.userAgent)

(我只想检测设备是否是iOS应用程序的目标)


2
关于正则表达式的重要说明(通常),感谢您在此处指出(多数地方出了错)!除了你的答案,应该时下检查!window.MSStream以及排除微软的浏览器按照这个回答另一个问题。并且!/CriOS/.test(navigator.userAgent)适用于希望根据此答案将Chrome过滤掉的用户。
Caw

1

实际上,检测移动性野生动物园并没有灵丹妙药。有相当多的浏览器可以使用移动浏览器用户代理的关键字。也许您可以尝试特征检测并不断更新规则。


1
例如,就我而言不。我想显示为iOS + Chrome制作的自定义智能横幅,但不希望在iOS + Safari上显示此横幅,因为iOS + Safari已经具有内置的智能横幅。
JobaDiniz 2015年

@JobaDiniz我知道很多人只想在移动浏览器中做某事,而不想在其他浏览器中做,我也是。但是,事实上,与令牌匹配的浏览器如“ iPad”,“ iOS”,“ iPhone”等。并不意味着它们是移动浏览器,也许它们是iOS的其他一些浏览器。例如,中国的UC和QQ浏览器。所有这些浏览器都可能使用safari的核心,大多数行为与移动safari相同,但有些行为则不同。糟透了
2015年

确实很烂。愚蠢的我曾经希望navigator.appname会有所不同,所有的iOS浏览器都是'Netscape'。但是,Safari是唯一能够安装配置配置文件的设备,因此,如果其他任何安装了.mobileconfig的设备,它都会下载该文件并看上去很愚蠢,因为它不知道哪个应用程序可以打开它...
Mitch Match

1

我知道这是一个老话题,但我想与大家分享我的解决方案。

我需要检测用户何时从Desktop Safari导航(因为我们在2017年中期,而Apple没有提供对input[type="date"]YET的任何支持...

因此,我为此做了一个后备自定义datepicker)。但仅适用于桌面版的safari,因为该输入类型在移动Safari中可以正常工作。因此,我使此正则表达式仅检测桌面Safari。我已经测试过了,它与Opera,Chrome,Firefox或Safari Mobile不匹配。

希望它可以帮助你们中的一些人。

if(userAgent.match(/^(?!.*chrome).(?!.*mobile).(?!.*firefox).(?!.*iPad).(?!.*iPhone).*safari.*$/i)){
  $('input[type="date"]').each(function(){
    $(this).BitmallDatePicker();
  })
}

1

我赞成@unwitting的答案,因为这不可避免地使我前进。但是,在iOS Webview中渲染SPA时,我需要对其进行一些调整。

function is_iOS () {
    /*
        Returns (true/false) whether device agent is iOS Safari
    */
    var ua = navigator.userAgent;
    var iOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i);
    var webkitUa = !!ua.match(/WebKit/i);

    return typeof webkitUa !== 'undefined' && iOS && webkitUa && !ua.match(/CriOS/i);
};

主要区别在于webkitto的重命名,以webkitUa防止与webkit用作SPA&UIView之间的消息处理程序的根对象发生冲突。


这工作了。返回typeof webkitUa!=='undefined'&& iOS && webkitUa &&!ua.match(/ CriOS / i);
Vignesh Chinnaiyan

0
function isIOS {
  var ua = window.navigator.userAgent;
  return /(iPad|iPhone|iPod).*WebKit/.test(ua) && !/(CriOS|OPiOS)/.test(ua);
}

0

我一直在寻找这个答案,我记得我以前曾遇到过这个问题。

在JavaScript中检测iOS上Safari的最可靠方法是

if (window.outerWidth === 0) {
    // Code for Safari on iOS
} 

or 

if (window.outerHeight === 0) {
    // Code for Safari on iOS
} 

由于某些原因,iOS上的Safari对于window.outerHeight属性和window.outerWidth属性返回0。

这适用于所有版本的iOS上的所有iPad和iPhone。其他所有浏览器和设备都可以正常使用此属性。

不知道他们是否打算更改此设置,但目前效果很好。


0

这个正则表达式适合我,干净简单

const isIOSSafari = !! window.navigator.userAgent.match(/ Version / [\ d。] +。* Safari /);


如果主机应用未显式添加Safari到自定义用户代理字符串中,则此方法不适用于嵌入式WKWebView 。
mrgrieves

iPad Safari现在默认处于说谎状态。
卡萨巴·托斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.