一、iPad 适配的 bug
近期用户需求做 iPad 适配时,有这样一个 分享出来的 H5 页面,如果是在 ipad 和 移动端的 浏览器中打开,要唤起 App 并打开对应的应用,结果 在 iOS13 的 iPad 上,没有反应,测试同学提了 Bug.
原因:iOS13 iPad 的 userAgent 中,没有了 ipad 字样,导致没有走 ipad 的逻辑。
相关 iPad 的 userAgent:
iPad iOS13.5,
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15
iPad iOS12.4.6,
Mozilla/5.0 (iPad; CPU OS 12_4_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Mobile/15E148 Safari/604.1
iPad Mini iOS13.1.3
Mozilla/5.0 (iPad; CPU iPhone OS 13_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1
从上面可以看到,从iOS13.5 开始,iPad设备获取的userAgent值中不再包含“iPad”字段了,而变成了“Macintosh”字段,不过奇怪的是,同样是iOS13的iPad Mini设备获取的userAgent值中却仍然有“iPad”字段。
二、起因
WWDC2019苹果发布了iOS13和iPad OS,从此iPad有了自己的操作系统。
随着iPad的尺寸越来越大,苹果为了更好的用户体验,一屏幕内可以展示更多的内容,在iOS13中,苹果改进Safari,新增了一项功能——“请求桌面网站”。通俗地讲,就是为了让iPad用起来像PC[狗头]。而且这个功能还“默认”开启,通过iPad设备打开Safari进入网站时会访问PC网站,而不是移动端网站。那么怎么实现这个功能呢?聪明的苹果工程师想了个好办法——改userAgent值不就完了吗?假装自己是PC骗过所有人,完美,就这么干!
三、纯前端解决方案
/*
* ipad环境判断更新
* iOS pre 13 以前以ua作判断,13后以platform及maxTouchPoints做判断
*/
isiPad = (navigator.userAgent.match(/(iPad)/) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1))
iOS13以前navigator.platform返回"iPhone"或"iPad";iOS13以后的iPad,navigator.platform返回"MacIntel",相当于Mac,由于目前还没有触摸屏的Mac,所以可以通过最大触控点来区分Mac和iPad的。当然这个方案并不严谨,说不定未来苹果就推出触摸屏的Mac了。我在网上也没有找到最佳解决方案,但至少,目前来看这个方法能解决问题。如果你有更好的方案,欢迎分享。