检测设备是否为 iOS检测 iOS检测 iOS 版本

我想知道是否有可能检测浏览器是否在iOS上运行,类似于使用Modernizr进行功能检测的方式(尽管这显然是设备检测而不是功能检测)。

通常我会更喜欢功能检测,但我需要找出设备是否是iOS,因为他们处理视频的方式,根据这个问题YouTube API不适用于iPad / iPhone /非闪存设备


答案 1

检测 iOS

iOS 13 iPad中,用户代理和平台字符串都会发生变化并且似乎可以区分iPad和MacOS,因此下面的所有答案现在都需要考虑这一点。

这可能是也涵盖iOS 13的最短替代方案:

function iOS() {
  return [
    'iPad Simulator',
    'iPhone Simulator',
    'iPod Simulator',
    'iPad',
    'iPhone',
    'iPod'
  ].includes(navigator.platform)
  // iPad on iOS 13 detection
  || (navigator.userAgent.includes("Mac") && "ontouchend" in document)
}

iOS将是truefalse

更糟糕的选项:用户代理嗅探

用户代理嗅探更危险,问题经常出现。

在iPad iOS 13上,用户代理与MacOS 13计算机的用户代理相同,但是如果您忽略iPad,则可能会在一段时间内仍然有效:

var iOS = !window.MSStream && /iPad|iPhone|iPod/.test(navigator.userAgent); // fails on iPad iOS 13

这是为了不错误地检测IE11,请参阅此处此处!window.MSStream

注意:两者都可以被用户或浏览器扩展伪造。navigator.userAgentnavigator.platform

浏览器扩展以更改用户代理或平台的存在是因为网站使用过于严厉的检测,并且经常禁用某些功能,即使用户的浏览器能够以其他方式使用该功能。

为了缓解与用户的这种冲突,建议针对每种情况下专门检测您的网站需要的确切功能。然后,当用户获得具有所需功能的浏览器时,它将无需更改其他代码即可工作。

检测 iOS 版本

检测 iOS 版本的最常见方法是从用户代理字符串中解析它。但也有特征检测推断*;

我们知道一个事实,即在iOS4中引入 - 在iOS5中 - 在iOS6中 - 在iOS7中,依此类推。history APImatchMedia APIwebAudio APIWebSpeech API

注意:以下代码不可靠,如果在较新的iOS版本中不推荐使用这些HTML5功能中的任何一个,则会中断。你已被警告!

function iOSversion() {

  if (iOS) { // <-- Use the one here above
    if (window.indexedDB) { return 'iOS 8 and up'; }
    if (window.SpeechSynthesisUtterance) { return 'iOS 7'; }
    if (window.webkitAudioContext) { return 'iOS 6'; }
    if (window.matchMedia) { return 'iOS 5'; }
    if (window.history && 'pushState' in window.history) { return 'iOS 4'; }
    return 'iOS 3 or earlier';
  }

  return 'Not an iOS device';
}

答案 2

在iOS 13之后,您应该像这样检测iOS设备,因为iPad不会通过旧方式被检测为iOS设备(由于新的“桌面”选项,默认情况下启用):

let isIOS = /iPad|iPhone|iPod/.test(navigator.platform)
|| (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)

iOS的第一个条件<13或iPhone或iPad禁用桌面模式,iPadOS 13的默认配置中的第二个条件,因为它的位置像Macintosh Intel,但实际上是唯一具有多点触控功能的Macintosh。

与其说是真正的解决方案,不如说是黑客攻击,但对我来说是可靠的

附言如前所述,您可能应该添加IE检查

let isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream