javascript 如何在 iOS 13 上的 Safari 中检测设备名称,但未显示正确的用户代理?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/58019463/
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
How to detect device name in Safari on iOS 13 while it doesn't show the correct user agent?
提问by Saeid Amanzadeh
After Apple's iOS 13 reales, I realized window.navigator.userAgentin Safari on iPad iOS 13 is same as on MacOS. Something like this:
在 Apple 的 iOS 13 reales 之后,我意识到iPad iOS 13 上的 Safari 中的window.navigator.userAgent与 MacOS 上的相同。像这样的东西:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15
As you see, it's a wrong user-agent for iPad and even there is no way to detect if the current device is an iDevice.
如您所见,这是一个错误的 iPad 用户代理,甚至无法检测当前设备是否为 iDevice。
After an initial research, I found a work around for it:
经过初步研究,我找到了解决方法:
Go to Settings -> Safari -> Request Desktop Website -> All websites. You notice "All websites" is enabled by default. If you disableit and get window.navigator.userAgent the correct user agent is now displayed.
转到设置 -> Safari -> 请求桌面网站 -> 所有网站。您注意到“所有网站”默认处于启用状态。如果您禁用它并获取 window.navigator.userAgent,则现在会显示正确的用户代理。
but I cannot ask each user to do this setting change for each device. So I tried to find another way and ended up by writing the following code which checks if it's Safari, macOS, and touch-screen then the device should be an apple mobile device, but I'm wondering is there any better suggestion/way to detect the correct device name in Safari iOS 13?
但我不能要求每个用户为每个设备进行此设置更改。所以我试图找到另一种方法,最后通过编写以下代码来检查它是否是 Safari、macOS 和触摸屏,然后设备应该是苹果移动设备,但我想知道有没有更好的建议/方法在 Safari iOS 13 中检测到正确的设备名称?
detectOs = function(){
//returns OS name, like "mac"
};
//is Safari on an apple touch-screen device
isSafariInIdevice = function(){
if (/Safari[\/\s](\d+\.\d+)/.test(windows.navigator.userAgent)) {
return 'ontouchstart' in window && detectOs() === "mac";
}
return false;
};
回答by kikiwora
Indeed, while option change in Settings may be a good solution for the user, as a developer you can't rely on that. It is as weird as to ask the user to not to use dark mode cause your app doesn't support it instead of opt-out of it using plist.
事实上,虽然设置中的选项更改对用户来说可能是一个很好的解决方案,但作为开发人员,您不能依赖它。要求用户不要使用暗模式,因为您的应用不支持它而不是使用 plist 选择退出它,这很奇怪。
As for me, the most simple way to detect iOS / iPad OS device now:
至于我,现在检测 iOS / iPad OS 设备的最简单方法:
let isIOS = /iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)
The first condition is old-fashioned and works with previous versions, while the second condition works for iPad OS 13 which now identifies itself as "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko)", which by all platform detectors I know is not detected (for now) neither as mobile nor desktop.
第一个条件是老式的并且适用于以前的版本,而第二个条件适用于 iPad OS 13,它现在将自己标识为“Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko )”,我所知道的所有平台检测器都没有检测到(目前),无论是移动设备还是桌面设备。
So since iPad OS now calls itself Macintosh, but real macs have no multi-touch support, this solution is ideal to detect iPad OS devices which are the only multi-touch "Macintosh" devices in existence.
因此,由于 iPad OS 现在自称为 Macintosh,但真正的 Mac 不支持多点触控,因此该解决方案非常适合检测 iPad OS 设备,这些设备是目前唯一的多点触控“Macintosh”设备。
P.S.Also, you may want to augment this checkup for IE exclusion from being detected as an iOS device
PS此外,您可能希望增强此检查以防止 IE 被检测为 iOS 设备
let isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream
回答by Mahmoud D. Alghraibeh
function mobileDetect() {
var agent = window.navigator.userAgent;
var d = document;
var e = d.documentElement;
var g = d.getElementsByTagName('body')[0];
var deviceWidth = window.innerWidth || e.clientWidth || g.clientWidth;
// Chrome
IsChromeApp = window.chrome && chrome.app && chrome.app.runtime;
// iPhone
IsIPhone = agent.match(/iPhone/i) != null;
// iPad up to IOS12
IsIPad = (agent.match(/iPad/i) != null) || ((agent.match(/iPhone/i) != null) && (deviceWidth > 750)); // iPadPro when run with no launch screen can have error in userAgent reporting as an iPhone rather than an iPad. iPadPro width portrait 768, iPhone6 plus 414x736 but would probably always report 414 on app startup
if (IsIPad) IsIPhone = false;
// iPad from IOS13
var macApp = agent.match(/Macintosh/i) != null;
if (macApp) {
// need to distinguish between Macbook and iPad
var canvas = document.createElement("canvas");
if (canvas != null) {
var context = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
if (context) {
var info = context.getExtension("WEBGL_debug_renderer_info");
if (info) {
var renderer = context.getParameter(info.UNMASKED_RENDERER_WEBGL);
if (renderer.indexOf("Apple") != -1) IsIPad = true;
}
;
}
;
}
;
}
;
// IOS
IsIOSApp = IsIPad || IsIPhone;
// Android
IsAndroid = agent.match(/Android/i) != null;
IsAndroidPhone = IsAndroid && deviceWidth <= 960;
IsAndroidTablet = IsAndroid && !IsAndroidPhone;
message = ""
if (IsIPhone) {
message = "Device is IsIPhone"
}
else if (IsIPad) {
message = "Device is ipad"
} else if (IsAndroidTablet || IsAndroidPhone || IsAndroid) {
message = "Device is Android"
} else {
message = "Device is Mac || Windows Desktop"
}
return {
message: message,
isTrue: IsIOSApp || IsAndroid || IsAndroidTablet || IsAndroidPhone
}
}
}
const checkMobile = mobileDetect()
const checkMobile = mobileDetect()
alert(checkMobile.message + " =====> " + checkMobile.isTrue) shareeditdeleteflag
alert(checkMobile.message + " ======> " + checkMobile.isTrue) shareeditdeleteflag
回答by itlijunjie
UIWebView *webView = [[UIWebView alloc] init];
NSString *command =[NSString stringWithFormat:@"navigator.userAgent"];
NSString *customUserAgent = [webView stringByEvaluatingJavaScriptFromString:command];
[(WKWebView *)_webView setCustomUserAgent:customUserAgent];

