区分iPadOS和macOS在网页上的方法

36

iPadOS测试版上的Safari用户代理与macOS上的Safari完全相同。有没有其他方法可以区分iPad和Mac?

iPad running iOS
Mozilla/5.0 (iPad; CPU OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1

iPadOS, developer beta 1
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS, beta 2, simulator
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS, beta 3, (simulator)
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS, developer beta 3
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS, developer beta 4
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS 13.1, developer beta 1
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS 13.1, developer beta 2
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

iPadOS 13.1, developer beta 3
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Safari/605.1.15

iPadOS 13.1, developer beta 4
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Safari/605.1.15

macOS Catalina 
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

macOS (older version)
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 Safari/605.1.15

macOS Catalina developer beta 7
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15

macOS Catalina developer beta 8
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Safari/605.1.15

播放HLS视频时,iPadOS代理似乎存在以下问题:
AppleCoreMedia/1.0.0.17A5821e (iPad; U; CPU OS 13_1 like Mac OS X; en_us)

2
我添加了下一个macOS Catalina的用户代理。请注意,它与iPadOS 完全相同 - Jonny
我认为你现在无法做到这一点。目前我的解决方案是,如果用户代理显示10.15,则显示一个弹出窗口询问是否为iPadOS或macOS。 - Alen Liang
1
我也在寻找解决这个问题的方法,唯一看到可能有用的是:Navigator.standalone来自 https://developer.mozilla.org/en-US/docs/Web/API/Navigator 的说明:“返回一个布尔值,指示浏览器是否在独立模式下运行。仅适用于苹果的iOS Safari。”正在尝试使用macOS 10.15的机器查看它是否在桌面safari上返回值,但在我的10.14 macOS safari中未定义。在我的模拟器中返回了10.15 iOS/ipadOS的值。 - user2879041
有趣,谢谢,我会在有时间的时候尝试在macOS 10.15上运行。但是即使现在可以工作,它似乎也非常脆弱。如果可能的话,我们应该将iPad视为桌面设备并继续前进。 - Jonny
@user2879041 iPadOS,开发者测试版4也返回了undefined,用于Navigator.standalone - Jonny
显示剩余5条评论
5个回答

45

我正在客户端使用这个测试:

   if (navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2) {
     ...must be iPad OS...

由于Mac没有官方触摸屏,所以看起来相当安全。顺便说一下,iPad上的maxTouchPoints的实际值为5。


13
对于那些说“这没什么关系(使用流体式网页设计)”的人,如果用户需要在Mac商店安装Safari应用/扩展或使用iOS共享扩展程序,则确实很重要。我需要提供正确的链接和指引。 - user984003
2
iPad在Chrome上的仿真仅支持1个maxTouchPoints,因此,除非您不打算使用Chrome进行调试,否则建议放弃> 2检查。 - Nadav

13

我通常不建议这样做,而且我没有进行过太多测试(自2019年9月以来在生产中使用类似的东西),但一种方法是在客户端检测TouchEvent的存在,并将其与用户代理的状态匹配,以解决iPad旧版本的问题。结果可能因人而异。未来可能不太安全。

function isIpad() {
    const ua = window.navigator.userAgent;
    if (ua.indexOf('iPad') > -1) {
        return true;
    }

    if (ua.indexOf('Macintosh') > -1) {
        try {
            document.createEvent("TouchEvent");
            return true;
        } catch (e) {}
    }

    return false;
}

2
isIpad() 在没有触摸功能的 MBP(Catalina)上的 Chrome 85 上返回 true。 - Simon B.

3

我正在使用这个,效果很好:

const ua = window.navigator.userAgent.toLowerCase();
const isiPad = ua.indexOf('ipad') > -1 || ua.indexOf('macintosh') > -1 && 'ontouchend' in document;

1
仅检查userAgent是不够的。也许navigator.maxTouchPoints > 2是一个足够好的权宜之计。 - Simon B.

2
如@Jonny提到的那样,您可以尝试检测触摸事件,这是我目前使用的解决方案。
function isTouchDevice() {
  if (typeof window === 'undefined') return false
  const prefixes = ' -webkit- -moz- -o- -ms- '.split(' ')
  function mq(query) {
    return typeof window !== 'undefined' && window.matchMedia(query).matches
  }
  if ('ontouchstart' in window || (window?.DocumentTouch && document instanceof DocumentTouch)) return true
  const query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('') // include the 'heartz' - https://git.io/vznFH
  return mq(query)
}

关于检测触摸事件的文章很有意思,链接在这里

另外需要注意的是,在iPad上使用Firefox的用户代理和Safari是一样的 :/


isTouchDevice()(5月24日版本)在没有触摸功能的MBP(Catalina)上的Chrome 85上返回true。也许navigator.maxTouchPoints > 2是一个足够好的临时解决方案。 - Simon B.

0
如果您使用 ua-parser-js解析User-Agent,您会发现iPad的“浏览器名称”是“移动Safari”,而Mac则是“Safari”。
如果用户在Chrome上登录,则对于iPad,parsedUA.device.model将为。
唯一的问题似乎在Firefox上……它将“Safari”作为“浏览器名称”,并将iPad的parsedUA.device.model标识为“Macintosh”……
(我试图完全依赖User-Agent,因为我从后端提取用户登录设备,并且没有关于用户设备的其他信息)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接