简体   繁体   English

确定用户是否从移动 Safari 导航

[英]Determine if user navigated from mobile Safari

I have an app, and I'd like to redirect the users to different pages based on where they are navigating from.我有一个应用程序,我想根据用户导航的位置将用户重定向到不同的页面。

If navigating from web clip, do not redirect.如果从网络剪辑导航,请勿重定向。 If navigating from mobile Safari, redirect to safari.aspx.如果从移动 Safari 导航,请重定向到 safari.aspx。 If navigating from anywhere else, redirect to unavailable.aspx如果从其他任何地方导航,请重定向到不可用的.aspx

I was able to use iPhone WebApps, is there a way to detect how it was loaded?我能够使用iPhone WebApps,有没有办法检测它是如何加载的? Home Screen vs Safari? 主屏幕与 Safari? to determine if the user was navigating from a web clip, but I'm having trouble determining if the user navigated from mobile Safari on an iPhone or iPod.确定用户是否从网络剪辑导航,但我无法确定用户是否从 iPhone 或 iPod 上的移动 Safari 导航。

Here's what I have:这是我所拥有的:

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";
}

See https://developer.chrome.com/multidevice/user-agent#chrome_for_ios_user_agent - the user agent strings for Safari on iOS and for Chrome on iOS are inconveniently similar:请参阅https://developer.chrome.com/multidevice/user-agent#chrome_for_ios_user_agent - iOS 上的 Safari 和 iOS 上的 Chrome 的用户代理字符串非常相似:

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

Safari苹果浏览器

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

Looks like the best approach here is to first of all check for iOS as other answers have suggested and then filter on the stuff that makes the Safari UA unique, which I would suggest is best accomplished with "is AppleWebKit and is not CriOS":看起来这里最好的方法是首先检查 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);

UPDATE : This is a very old answer and I cannot delete it because the answer is accepted.更新:这是一个非常古老的答案,我无法删除它,因为答案已被接受。 Check unwitting's answer below for a better solution.检查下面不知情的答案以获得更好的解决方案。


You should be able to check for the "iPad" or "iPhone" substring in the user agent string:您应该能够检查用户代理字符串中的“iPad”或“iPhone”子字符串:

var userAgent = window.navigator.userAgent;

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

best practice is:最佳做法是:

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

Merged all the answers and comments.合并所有答案和评论。 This is the result.这就是结果。

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


// Usage:
// if iOSSafari(window.navigator.userAgent) { /* iOS Safari code here */ }

// Testing:
var iPhoneSafari = [
  "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1",
  "Mozilla/5.0 (Apple-iPhone7C2/1202.466; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543 Safari/419.3",
  "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1",
  "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1",
  "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A5370a Safari/604.1",
  "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1",
  "Mozilla/5.0 (iPhone9,3; U; CPU iPhone OS 10_0_1 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/14A403 Safari/602.1",
  "Mozilla/5.0 (iPhone9,4; U; CPU iPhone OS 10_0_1 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/14A403 Safari/602.1",
];
console.log("All true:", iPhoneSafari.map(iOSSafari));

var iPhoneNotSafari = [
  "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/69.0.3497.105 Mobile/15E148 Safari/605.1",
  "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/13.2b11866 Mobile/16A366 Safari/605.1.15",
];
console.log("All false:", iPhoneNotSafari.map(iOSSafari));

Falling code only find mobile safari and nothing else (except dolphin and other small browsers) Falling code 只找到移动 safari 没有别的(除了 dolphin 和其他小浏览器)

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

Seeing all the answers, here are some tips about the proposed RegExes:看到所有的答案,这里有一些关于建议的正则表达式的提示:

  • AppleWebKit matches Desktop Safari too (not only mobile) AppleWebKit也与桌面 Safari 匹配(不仅是移动设备)
  • no need to call .match more than once for such simple regexes, and prefer the lighter .test method.对于这样简单的正则表达式,无需多次调用.match ,而更喜欢更轻的.test方法。
  • the g (global) regex flag is useless while the i (case insensitive) can be useful g (全局)正则表达式标志无用,而i (不区分大小写)可能有用
  • no need for capture (parenthesis), we are just testing the string不需要捕获(括号),我们只是测试字符串

I'm just using this since getting true for mobile Chrome is OK for me (same behavior):我只是使用它,因为移动 Chrome 对我来说是true的(相同的行为):

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

(I just want to detect if the device is a target for an iOS app) (我只想检测设备是否是 iOS 应用程序的目标)

这个正则表达式对我有用,干净简单:

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

Actually, there isn't a silver bullet of detecting mobile safari.实际上,没有检测移动 safari 的灵丹妙药。 There are quite a few browsers may use the keywords of the user agent of mobile safari.有不少浏览器可能会使用mobile safari的user agent的关键字。 Maybe you can try feature detection and keep updating the rule.也许您可以尝试特征检测并不断更新规则。

I upvoted @unwitting 's answer, as it inevitably got me going.我赞成@unwitting 的答案,因为它不可避免地让我前进。 However, when rendering my SPA in an iOS Webview, I needed to tweak it a bit.但是,当在 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);
};

The main difference being, the renaming of webkit to webkitUa , so as to prevent clashing with the root webkit object used as a message handler between the SPA & UIView.主要区别在于,将webkit重命名为webkitUa ,以防止与用作 SPA 和 UIView 之间的消息处理程序的根webkit对象发生冲突。

I know this is an old thread, but I'd like to share my solution with you guys.我知道这是一个旧线程,但我想与你们分享我的解决方案。

I needed to detect when an user navigates from Desktop Safari (Because we're in middle 2017, and Apple hasn't give any support for input[type="date"] YET...我需要检测用户何时从桌面 Safari 导航(因为我们正处于 2017 年中期,而 Apple 尚未对input[type="date"]提供任何支持......

So, I made a fallback custom datepicker for it) .所以,我为它做了一个后备自定义日期选择器)。 But only applies to safari in desktop because that input type works fine in mobile Safari.但仅适用于桌面版 Safari,因为该输入类型在移动版 Safari 中运行良好。 So, I made this Regex to only detect desktop Safari.所以,我做了这个正则表达式只检测桌面 Safari。 I already tested it and it doesn't match with Opera, Chrome, Firefox or Safari Mobile.我已经对其进行了测试,但它与 Opera、Chrome、Firefox 或 Safari Mobile 不匹配。

Hope it may help some of you guys.希望它可以帮助你们中的一些人。

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

I was looking for this answer and I remembered I came across this before.我一直在寻找这个答案,我记得我以前遇到过这个。

The most reliable way to detect Safari on iOS in JavaScript is用 JavaScript 在 iOS 上检测 Safari 最可靠的方法是

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

or 

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

For some reason Safari on iOS returns 0 for window.outerHeight property and window.outerWidth property.由于某种原因,iOS 上的 Safari 为 window.outerHeight 属性和 window.outerWidth 属性返回 0。

This is for all iPads and iPhones on all versions of iOS.这适用于所有 iOS 版本上的所有 iPad 和 iPhone。 Every other browser and device this property works normally.其他所有浏览器和设备此属性都可以正常工作。

Not sure if they intend to change this but for now it works well.不确定他们是否打算改变这一点,但目前它运作良好。

如果有人需要,这里基于不知情的答案是正则表达式。

/^(?=.*(iPhone|iPad|iPod))(?=.*AppleWebKit)(?!.*(criOS|fxiOS|opiOS|chrome|android)).*/i

It's been many years and Apple still hasn't fixed their bottom fixed positioning ( 100vh ) bug on mobile Safari.已经很多年了,Apple 仍然没有修复他们在移动 Safari 上的底部固定定位 ( 100vh ) 错误。 Even though every other browser works fine.即使其他所有浏览器都可以正常工作。

So, There's also a vender property that'll say "Google, Inc" for Chrome and even Brave, other Webkit browsers if the userAgent is Webkit Safari unless it says "Apple Computer Inc."因此,如果 userAgent 是 Webkit Safari,除非它显示“Apple Computer Inc.”,否则对于 Chrome 甚至 Brave 以及其他 Webkit 浏览器,还有一个供应商属性会显示“Google, Inc”。 in which case it's Safari.在这种情况下,它是 Safari。

To avoid false positives in Desktop Safari, you need the maxTouchPoints property as well, which will be 5 for mobile and 0 for desktop.为避免桌面 Safari 中的误报,您还需要 maxTouchPoints 属性,移动设备为 5,桌面设备为 0。 Horrifying, I know.可怕,我知道。

const isSafari =
  navigator.userAgent.match(/safari/i) &&
  navigator.vendor.match(/apple/i) &&
  navigator.maxTouchPoints;

if (isSafari) 
  $("body").classList.add("mobile-safari");

Then make adjustments in the CSS using that mobile-safari class.然后使用该mobile-safari类在 CSS 中进行调整。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM