我想知道是否有可能检测浏览器是否运行在iOS上,类似于你如何使用Modernizr进行功能检测(尽管这显然是设备检测而不是功能检测)。
通常情况下,我会倾向于功能检测,但我需要找出设备是否是iOS,因为他们处理视频的方式根据这个问题,YouTube API不适用于iPad / iPhone /非flash设备
我想知道是否有可能检测浏览器是否运行在iOS上,类似于你如何使用Modernizr进行功能检测(尽管这显然是设备检测而不是功能检测)。
通常情况下,我会倾向于功能检测,但我需要找出设备是否是iOS,因为他们处理视频的方式根据这个问题,YouTube API不适用于iPad / iPhone /非flash设备
当前回答
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要么为真,要么为假
更糟糕的选择:用户代理嗅探
用户代理嗅探更加危险,经常出现问题。
在iPad iOS 13上,用户代理与MacOS 13计算机上的用户代理相同,但如果你忽略iPad,这可能仍然可以工作一段时间:
var iOS = !window.MSStream && /iPad|iPhone|iPod/.test(navigator.userAgent); // fails on iPad iOS 13
!窗口。MSStream是为了不错误地检测IE11,请看这里和这里。
注意:都是导航器。userAgent和navigator。平台可以被用户或浏览器扩展伪造。
改变userAgent或平台的浏览器扩展存在,因为网站使用了过于繁重的检测,并且经常禁用一些功能,即使用户的浏览器本来可以使用这些功能。
为了减少与用户的冲突,建议针对每种情况专门检测您的网站需要的确切功能。然后,当用户得到一个具有所需功能的浏览器时,它就已经可以工作了,而无需额外的代码更改。
检测iOS版本
检测iOS版本的最常见方法是从User Agent字符串中解析它。但也有特征检测推断*;
我们知道,历史API是在iOS4中引入的,matchMedia API是在iOS5中引入的,webAudio API是在iOS6中引入的,WebSpeech API是在iOS7中引入的,等等。
注意:以下代码是不可靠的,如果这些HTML5功能中的任何一个在更新的iOS版本中被弃用,就会中断。我警告过你!
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';
}
其他回答
以上所有答案都不适用于所有版本的iOS(包括iOS 13)上的所有主要浏览器。下面是一个适用于所有iOS版本的Safari、Chrome和Firefox的解决方案:
var isIOS = (function () {
var iosQuirkPresent = function () {
var audio = new Audio();
audio.volume = 0.5;
return audio.volume === 1; // volume cannot be changed from "1" on iOS 12 and below
};
var isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
var isAppleDevice = navigator.userAgent.includes('Macintosh');
var isTouchScreen = navigator.maxTouchPoints >= 1; // true for iOS 13 (and hopefully beyond)
return isIOS || (isAppleDevice && (isTouchScreen || iosQuirkPresent()));
})();
请注意,此代码片段的编写优先考虑的是可读性,而不是简洁性或性能。
解释:
If the user agent contains any of "iPod|iPhone|iPad" then clearly the device is iOS. Otherwise, continue... Any other user agent that does not contain "Macintosh" is not an Apple device and therefore cannot be iOS. Otherwise, it is an Apple device, so continue... If maxTouchPoints has a value of 1 or greater then the Apple device has a touch screen and therefore must be iOS since there are no Macs with touch screens (kudos to kikiwora for mentioning maxTouchPoints). Note that maxTouchPoints is undefined for iOS 12 and below, so we need a different solution for that scenario... iOS 12 and below has a quirk that does not exist in Mac OS. The quirk is that the volume property of an Audio element cannot be successfully set to any value other than 1. This is because Apple does not allow volume changes on the Audio element for iOS devices, but does for Mac OS. That quirk can be used as the final fallback method for distinguishing an iOS device from a Mac OS device.
如果您正在使用Modernizr,您可以为它添加一个自定义测试。
决定使用哪种检测模式并不重要(userAgent, navigator。Vendor或navigator.platform),您总是可以将其打包以便稍后使用。
//Add Modernizr test
Modernizr.addTest('isios', function() {
return navigator.userAgent.match(/(iPad|iPhone|iPod)/g);
});
//usage
if (Modernizr.isios) {
//this adds ios class to body
Modernizr.prefixed('ios');
} else {
//this adds notios class to body
Modernizr.prefixed('notios');
}
如果你还在尝试检查是否是iOS,我建议你使用以下方法:
创建一个名为helper的文件夹 创建一个名为platform的文件。Ts或platform.js 导出函数isIOS:
export const isIOS = () => {
let platform = navigator?.userAgent || navigator?.platform || 'unknown'
return /iPhone|iPod|iPad/.test(platform)
}
如果是iPhone或iPod或Ipad,结果为真,否则为假。
你可能会问,为什么我需要检查导航器。userAgent || navigator。平台,原因很简单,第二个选项曾经是默认选项,但现在它已弃用,一些浏览器将在未来停止支持它,第一个选项更可靠。
你可以在这里查看我上面提到的反对意见:
https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform: ~:文本3 =弃用% % 20这% % 20 20特性是% 20不,% 20保持% 20 % 20兼容性% 20目的。
记录userAgentData、userAgent和平台。
使用下面的函数,我收到了这些日志:
console.log({
userAgentData: navigator?.userAgentData?.platform,
userAgent: navigator?.userAgent,
platform: navigator?.platform,
})
{
"userAgentData": "",
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
"platform": "MacIntel"
}
我在自己的Macbook电脑上测试了它,它在不同的浏览器和操作系统上都能运行。你可以看到navigator?。useragentdata ?。平台根本不起作用。
我也没有收到任何与我的typescript相关的错误,即使我使用React调用这个函数。
奖金、isAndroid
如果你想知道如何检查是否是Android平台,我建议你不要遵循与isIOS相反的想法:
const isAndroid = !isIOS();
原因很简单,因为桌面将被视为Android平台,所以它将无法工作。 要解决这个问题,你只需要做以下检查:
export const isAndroid = () => {
const ua = navigator.userAgent.toLowerCase() + navigator?.platform.toLowerCase();
const isAndroid = ua.indexOf("android") > -1;
return isAndroid;
}
我们检查导航器的原因。userAgent + navigator?平台支持新旧浏览器。
var isiOSSafari = (navigator.userAgent. var)match(/like Mac OS X/i)) ?真:假;
我在几年前写过这个,但我相信它仍然有效:
if(navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.match(/iPhone/i) || (navigator.userAgent.match(/iPod/i)))
{
alert("Ipod or Iphone");
}
else if (navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.match(/iPad/i))
{
alert("Ipad");
}
else if (navigator.vendor != null && navigator.vendor.match(/Apple Computer, Inc./) && navigator.userAgent.indexOf('Safari') != -1)
{
alert("Safari");
}
else if (navigator.vendor == null || navigator.vendor != null)
{
alert("Not Apple Based Browser");
}