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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3007480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:52:56  来源:igfitidea点击:

Determine if user navigated from mobile Safari

javascriptiphonemobile-safariweb-clips

提问by Steven

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. If navigating from anywhere else, redirect to unavailable.aspx

如果从网络剪辑导航,请勿重定向。如果从移动 Safari 导航,请重定向到 safari.aspx。如果从其他任何地方导航,重定向到不可用.aspx

I was able to use iPhone WebApps, is there a way to detect how it was loaded? Home Screen vs 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 WebApps,有没有办法检测它是如何加载的?主屏幕 vs Safari?以确定用户是否从网络剪辑导航,但我无法确定用户是否从 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";
}

采纳答案by Daniel Vassallo

UPDATE: This is a very old answer and I cannot delete it because the answer is accepted. Check unwitting's answer belowfor a better solution.

更新:这是一个非常古老的答案,我无法删除它,因为答案已被接受。检查下面不知情的答案以获得更好的解决方案。



You should be able to check for the "iPad" or "iPhone" substring in the user agentstring:

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

var userAgent = window.navigator.userAgent;

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

回答by unwitting

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

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

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);

回答by appsthatmatter

best practice is:

最佳做法是:

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

回答by aWebDeveloper

Falling code only find mobile safari and nothing else (except dolphin and other small browsers)

下降码只找到移动端safari,没有别的(除了dolphin等小浏览器)

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

回答by Константин Ван

Merged all the answers and comments. And 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));
}



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));

回答by antoine129

Seeing all the answers, here are some tips about the proposed RegExes:

看到所有答案,以下是有关提议的 RegEx 的一些提示:

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

I'm just using this since getting truefor mobile Chrome is OK for me (same behavior):

我只是使用它,因为true移动 Chrome 对我来说是可以的(相同的行为):

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

(I just want to detect if the device is a target for an iOS app)

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

回答by pimbrouwers

I upvoted @unwitting 's answer, as it inevitably got me going. However, when rendering my SPA in an iOS Webview, I needed to tweak it a bit.

我赞成 @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);
};

The main difference being, the renaming of webkitto webkitUa, so as to prevent clashing with the root webkitobject used as a message handler between the SPA & UIView.

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

回答by edd2110

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...

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

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. So, I made this Regex to only detect desktop Safari. I already tested it and it doesn't match with Opera, Chrome, Firefox or Safari Mobile.

所以,我为它做了一个后备自定义日期选择器)。但仅适用于桌面版 safari,因为该输入类型在移动版 Safari 中工作正常。所以,我让这个 Regex 只检测桌面 Safari。我已经对其进行了测试,但它与 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();
  })
}

回答by Light

Actually, there isn't a silver bullet of detecting mobile safari. There are quite a few browsers may use the keywords of the user agent of mobile safari. Maybe you can try feature detection and keep updating the rule.

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

回答by naeluh

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. Every other browser and device this property works normally.

这适用于所有 iOS 版本上的所有 iPad 和 iPhone。每个其他浏览器和设备此属性正常工作。

Not sure if they intend to change this but for now it works well.

不确定他们是否打算改变这一点,但目前它运作良好。