web-dev-qa-db-ja.com

正しいユーザーエージェントが表示されていないときにiOS 13のSafariでデバイス名を検出する方法

AppleのiOS 13が実現した後、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

ご覧のとおり、これはiPadのユーザーエージェントではなく、現在のデバイスがiDeviceかどうかを検出する方法さえありません。


最初の調査の後、私はその回避策を見つけました:

[設定]-> [Safari]-> [デスクトップウェブサイトのリクエスト]-> [すべてのウェブサイト]に移動します。 「すべてのWebサイト」がデフォルトで有効であることがわかります。 disableそれを取得してwindow.navigator.userAgentを取得すると、正しいユーザーエージェントが表示されます。

ただし、デバイスごとにこの設定変更を行うように各ユーザーに依頼することはできません。だから私は別の方法を見つけようとしましたSafari、macOS、タッチスクリーンであるかどうかをチェックする次のコードの場合、デバイスはAppleモバイルデバイス)である必要がありますしかし、私は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;
};
47
Saeid Amanzadeh

確かに、設定のオプション変更はユーザーにとって良い解決策かもしれませんが、開発者としてそれを信頼することはできません。ダークモードを使用しないようにユーザーに要求するのは奇妙ですが、アプリはplistを使用してオプトアウトするのではなく、サポートしていません。

私としては、iOS/iPad OSデバイスを検出する最も簡単な方法は次のとおりです。

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

最初の条件は旧式で以前のバージョンで機能しますが、2番目の条件はiPad OS 13で機能し、「Mozilla/5.0(Macintosh; Intel Mac OS X 10_15)AppleWebKit/605.1.15(KHTML、like Gecko ) "、私が知っているすべてのプラットフォーム検出器では、モバイルでもデスクトップでも(今のところ)検出されていません。

IPad OSはMacintoshと呼ばれるようになりましたが、実際のMacはマルチタッチをサポートしていないため、このソリューションは、存在する唯一のマルチタッチ「Macintosh」デバイスであるiPad OSデバイスを検出するのに理想的です。

P.S。また、この診断を拡張して、IE iOSデバイスとして検出されないように除外することもできます。

let isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)) &&
!window.MSStream
52
kikiwora
 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()

alert(checkMobile.message + "=====>" + checkMobile.isTrue)shareeditdeleteflag