ตรวจจับ ipad / iphone webview ผ่าน javascript


91

มีวิธีที่แตกต่างกันผ่านทางจาวาสคริปต์หากเว็บไซต์ทำงานในซาฟารี iPad หรือภายใน WebView ของแอปพลิเคชัน


นี่เป็นเพียงสำหรับอุปกรณ์ iOS หรือไม่
Nicolas S

คำตอบ:


80

นี้จะใช้การรวมกันของและwindow.navigator.userAgent window.navigator.standaloneสามารถแยกความแตกต่างระหว่างสถานะทั้งสี่ที่เกี่ยวข้องกับเว็บแอป iOS: ซาฟารี (เบราว์เซอร์), สแตนด์อโลน (เต็มหน้าจอ), uiwebview และไม่ใช่ iOS

การสาธิต: http://jsfiddle.net/ThinkingStiff/6qrbn/

var standalone = window.navigator.standalone,
    userAgent = window.navigator.userAgent.toLowerCase(),
    safari = /safari/.test( userAgent ),
    ios = /iphone|ipod|ipad/.test( userAgent );

if( ios ) {
    if ( !standalone && safari ) {
        //browser
    } else if ( standalone && !safari ) {
        //standalone
    } else if ( !standalone && !safari ) {
        //uiwebview
    };
} else {
    //not iOS
};

chrome มีSafariใน userAgent มันทำงานแตกต่างกันไปตามความต้องการwebcal://โปรโตคอลสำหรับไฟล์. ics
neaumusic

@svlada สามารถให้ข้อมูลเพิ่มเติมได้หรือไม่? อุปกรณ์ของคุณและ iOS เวอร์ชันใด
sonlexqt

ไม่ทำงานบน iOS 13 และ 14
Alex Sorokoletov

78

ตัวแทนผู้ใช้

ทำงานใน UIWebView

Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/98176

ทำงานใน Safari บน iPad

Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3

ทำงานใน Safari บน Mac OS X

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.5 Safari/534.55.3

ทำงานใน Chrome บน Mac OS X

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.151 Safari/535.19

ทำงานใน FireFox บน Mac OS X

Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0

รหัสการตรวจจับ

var is_uiwebview = /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent);
var is_safari_or_uiwebview = /(iPhone|iPod|iPad).*AppleWebKit/i.test(navigator.userAgent);

จริงๆ. ฉันไม่รู้ว่าทำไมฉันถึงมองไปที่ useragents ทั้งสองด้วยตัวเองในตอนแรก ขอบคุณสำหรับคำตอบ :)
sod

4
ไม่ทำงานบน iPhone 5s / iOS 7 เนื่องจากทั้งสองUIWebViewและ Safari มีSafariตัวแทนผู้ใช้อยู่
Razor

@Razor คุณพูดถูก การทดสอบเทียบกับVersionการSafariทำงานสำหรับฉันใน iOS ล่าสุด
unceus

1
@unceus ช่วยสรุปความหมายของคุณได้Versionไหม? คุณแทนที่Safariด้วยVersionในvar is_uiwebviewบรรทัดหรือไม่?
Henrik Petterson

@HenrikPetterson เกี่ยวกับสตริงตัวแทนผู้ใช้การเปรียบเทียบสตริงตัวแทนผู้ใช้สองรายการแรกด้านบน (UIWebView และ Safari บน iPad) สตริง UIWebView มี 'เวอร์ชัน' ในขณะที่ ipad หนึ่งไม่มี เป้าหมายของคุณในการแก้ไขนิพจน์ทั่วไปนั้นไม่ชัดเจนและดูเหมือนว่าคุณอาจต้องการความช่วยเหลือในการเขียน
unceus

10

ฉันคิดว่าคุณสามารถใช้ไฟล์User-Agent.


อัปเดต

เรียกดูหน้าโดยใช้ iPhone Safari

Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7

ฉันจะลองใช้ UIWebView ในไม่กี่วินาที

Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Mobile/8B117

ความแตกต่างก็คือ Safari หนึ่งกล่าว Safari/6531.22.7


วิธีการแก้

var isSafari = navigator.userAgent.match(/Safari/i) != null;

ใช่ แต่คุณมีความคิดหรือไม่ว่ามีสตริงเฉพาะหรือบางอย่างที่จะตรวจจับ UIWebView ใน User-Agent? จนถึงตอนนี้ฉันไม่พบอะไรเลย ...
Adam Tal

นี่เป็นเพียงสำหรับอุปกรณ์ iOS หรือไม่
Nicolas S

Nicolas ตัวเลขจะแตกต่างกันในขณะนี้เนื่องจาก Safari และ UIWebView (และ "สแตนด์อะโลน" - นี่คือหน้าจอหลัก - เว็บแอป) ใช้เครื่องมือที่แตกต่างกัน การเปลี่ยนแปลงนี้ใน iOS 5
เบน

ฉันไม่ได้หมายถึงตัวเลขฉันหมายถึงSafari/.....ตัวมันเองหายไปใน UIWebView
Nicolas S

@ นิโคลัส: ถูกต้องขอโทษที่ฉันไม่ได้ให้ความสนใจ ฉันสงสัยว่าจะมีใครยืนยันได้ว่ายังคงเป็นเช่นนั้นใน iOS5 หรือไม่?
เบน

7

ใช่:

// is this an IPad ?
var isiPad = (navigator.userAgent.match(/iPad/i) != null);

// is this an iPhone ?
var isiPhone = (navigator.userAgent.match(/iPhone/i) != null);

// is this an iPod ?
var isiPod = (navigator.userAgent.match(/iPod/i) != null);

11
สิ่งนี้จะตรงกับเบราว์เซอร์ Safari ไม่เพียง แต่ WebView
Petr Peller

@ThinkingStuff - คุณช่วยฉันช่วยแยกความแตกต่างระหว่าง Mac OS (เบราว์เซอร์เดสก์ท็อป) กับเบราว์เซอร์ Safari ของ iPad - stackoverflow.com/questions/58344491/…
newdeveloper

6

ฉันได้ลองวิธีแก้ปัญหาเหล่านี้ทั้งหมดแล้ว แต่ไม่ได้ผลในกรณีของ
ฉันฉันจะตรวจพบTelegramใน Webview ฉันสังเกตเห็นว่า Safari กำลังเปลี่ยนข้อความรูปแบบโทรศัพท์เป็นลิงก์ที่มีคำนำหน้า "tel:" ฉันจึงใช้สิ่งนี้ในการเขียนโค้ดนี้คุณสามารถทดสอบได้: jsfiddle

<!DOCTYPE html>
<html>
<head></head>
<body>
<ul id="phone" style="opacity:0">
    <li>111-111-1111</li>
</ul>
</body>
</html>

<script>

    var html = document.getElementById("phone").innerHTML;

    if (navigator.platform.substr(0,2) === 'iP') {

        if (html.indexOf('tel:') == -1)
            alert('not safari browser');
        else
            alert('safari browser');
    }
    else
        alert('not iOS');
</script>

1
คุณไม่ควรพึ่งพาเคล็ดลับดังกล่าวเนื่องจากผู้ใช้หรือผู้พัฒนารายอื่นสามารถปิดใช้งานการตรวจจับโทรศัพท์ได้
БодровАндрей

@ БодровАндрейฉันเห็นด้วยกับคุณ แต่นั่นเป็นวิธีเดียวที่ฉันจะพบฉันหวังว่าแอปเปิลจะจัดหา User-Agent ที่แตกต่างออกไปในอนาคต
Amir Khorsandi

ระวังนี้จะ borken บน iOS 13 navigator.platform === 'MacIntel'เพราะถ้าโหมดสก์ท็อปที่ใช้แล้ว สิ่งนี้มีผลกับ iPadOS 13 Mobile Safari เป็นพิเศษเนื่องจากใช้โหมดเดสก์ท็อปตามค่าเริ่มต้น
robocat

@robocat คุณพูดถูก มันเสียใน iOS 13 iPad และตอนนี้ฉันติดอยู่โดยไม่มีวิธีแก้ไข โปรดช่วยฉันด้วยคำถามที่เกี่ยวข้องที่นี่stackoverflow.com/questions/58344491/…
newdeveloper

ใช้งานได้บน iOS 14
Alex Sorokoletov

2

โซลูชันของ Neoneye ไม่ทำงานอีกต่อไป (ดูความคิดเห็น) และสามารถทำให้ง่ายขึ้น ในทางกลับกันการทดสอบเฉพาะ "Safari" ใน UA นั้นมีมากกว่าอุปกรณ์มือถือ iOS

นี่คือการทดสอบที่ฉันใช้:

var is_ios = /(iPhone|iPod|iPad).*AppleWebKit.*Safari/i.test(navigator.userAgent);

2

โปรดทราบว่าวิธีนี้ใช้ไม่ได้กับ iOS 10 และเวอร์ชันเก่ากว่า

สำหรับฤดูใบไม้ผลิปี 2018 ไม่มีวิธีใดที่นำเสนอได้ผลสำหรับฉันดังนั้นฉันจึงคิดแนวทางใหม่ (ซึ่งไม่ใช่ userAgent):

const hasValidDocumentElementRatio =
  [ 320 / 454 // 5, SE
  , 375 / 553 // 6, 7, 8
  , 414 / 622 // 6, 7, 8 Plus
  , 375 / 812 // X
  , 414 / 896 // Xs, Xr
  ].some(ratio =>
    ratio === document.documentElement.clientWidth / 
      document.documentElement.clientHeight
  )

const hasSafariInUA = /Safari/.test(navigator.userAgent)

const isiOSSafari = hasSafariInUA && hasValidDocumentElementRatio  // <- this one is set to false for webviews

https://gist.github.com/BorisChumichev/7c0ea033daf33da73306a396ffa174d1

คุณสามารถขยายรหัสสำหรับอุปกรณ์ iPad ได้เช่นกันฉันคิดว่าควรทำเคล็ดลับ

ทำงานได้ดีกับ Telegram, Facebook, VK webviews


สำหรับ iPhone X จะเป็น 375/812 และใหม่ด้วย: 414/896 สำหรับ iPhone Xs Max / Xr
Oleg Dater

1

Working 15.02.19

วิธีการแก้ปัญหาสำหรับการตรวจสอบ webviews บน iOS อีกอย่างหนึ่งคือการตรวจสอบสำหรับการสนับสนุน / navigator.mediaDevicesการดำรงอยู่ของ

if (navigator.mediaDevices) {
    alert('has mediaDevices');
} else {
    alert('has no mediaDevices');
}

ในกรณีของฉันฉันไม่จำเป็นต้องจับดูเว็บวิวทั้งหมด แต่ที่ไม่รองรับอินพุตกล้อง / ไมโครโฟน (คำเตือน: การแจ้งเตือนไม่เรียกใช้ใน Webview ดังนั้นอย่าลืมเปลี่ยนบางอย่างใน Dom เพื่อจุดประสงค์ในการดีบัก)


0

ฉันรู้ว่ารหัสนี้จะตรวจสอบว่ามีการเข้าถึงจากไอคอนที่เพิ่มในหน้าจอหลักหรือไม่:

if (window.navigator.standalone == true) {
//not in safari
}

แต่ฉันไม่แน่ใจว่ามันจะตอบสนองอย่างไรใน UIWebView ทางออกเดียวที่ฉันคิดได้คือการรับตัวแทนผู้ใช้หรือการใช้- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationTypeและการแทนที่สตริงการสืบค้นของหน้าที่คุณกำลังเข้าถึงด้วยสิ่งที่เพจใช้เพื่อระบุว่ามีการเข้าถึงจากการดูเว็บ


ขอบคุณฉันใช้รหัสนั้น แต่ต้องการการควบคุมมากกว่านี้ ดูเหมือนว่าจะตรวจจับเฉพาะโหมดสแตนด์อโลนและถือว่าส่วนที่เหลือเป็น Safari
Adam Tal

0

ขอแนะนำให้ใช้Modernizr , และการตรวจสอบสำหรับ IndexedDB เช่นนี้ คุณสามารถตรวจสอบข้ามกับคอนฟิกูเรชันตัวแทนผู้ใช้ (อุปกรณ์, ระบบปฏิบัติการ, เบราว์เซอร์ ฯลฯ ) แต่การตรวจจับคุณสมบัติที่แท้จริงดูเหมือนจะแนะนำมากกว่า


ฟังดูเหมือนเป็นแผน แต่คุณจะทดสอบฟีเจอร์อะไร indexeddb เป็นส่วนหนึ่งของเช่น chrome, firefox ฯลฯ
SSED

0

ครั้งสุดท้ายที่ฉันต้องการสิ่งนี้ (เพียงเพื่อวัตถุประสงค์ของ WebView) ฉันใช้การตรวจสอบนี้:

function isIOS() {
     return !/safari/.test( window.navigator.userAgent.toLowerCase()) || navigator.platform === 'iOS' || navigator.platform === 'iPhone';
}

สิ่งนี้เสียในโหมดเดสก์ท็อป iOS13 (ไม่ได้ตั้งค่าแพลตฟอร์มเป็น iPad หรือ iPhone อีกต่อไป) และบน iPod touch (แพลตฟอร์มอาจเป็น "iPod" หรือ "iPod touch")
robocat

0

ฉันพบวิธีง่ายๆในการตรวจจับ iPhone หรือ iPad แล้ว วิธีนี้ใช้ได้ผลดีสำหรับฉัน

var is_iPad = navigator.userAgent.match(/iPad/i) != null;
var is_iPhone = navigator.userAgent.match(/iPhone/i) != null;
    if(is_iPad || is_iPhone == true){
        //perform your action
    }

0

ลองกับ IOS 13

      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)

-2

ฉันไม่คิดว่าจะมีอะไรที่เฉพาะเจาะจงที่คุณสามารถใช้ใน Javascript ฝั่งไคลเอ็นต์ได้ แต่ถ้าคุณสามารถควบคุมสิ่งที่ UIWebView เริ่มต้นสามารถทำได้คุณอาจต้องการพิจารณาเล่นกับสตริงตัวแทนผู้ใช้ที่สร้างขึ้นและทดสอบสิ่งนั้นใน Javascript ฝั่งไคลเอ็นต์แทน? ฉันรู้ว่าแฮ็คนิดหน่อย แต่เดี๋ยวก่อน ... คำถามนี้อาจให้คำแนะนำในการปรับแต่งตัวแทนผู้ใช้:

เปลี่ยน User Agent ใน UIWebView (iPhone SDK)


ขอบคุณเบ็น น่าเสียดายที่ฉันไม่สามารถควบคุมตัวแทนผู้ใช้ UIWebView ของแอปได้
Adam Tal

-7

@ Sod ฉันไม่มีคำตอบ แต่ฉันไม่มั่นใจว่าทำไมคุณถึงต้องการตรวจสอบเนื่องจากเอ็นจิ้นเบราว์เซอร์ว่าซาฟารี (เบราว์เซอร์) หรือแอปพลิเคชันจะเหมือนกันกับ Webkit เท่านั้นใช่แอปพลิเคชันสามารถกำหนดค่าความสามารถของเบราว์เซอร์เอ็นจินเช่น ไม่ว่าแอปพลิเคชันต้องการเรียกใช้ JS หรือ Display Image ฯลฯ ...

ฉันเชื่อว่าคุณต้องตรวจสอบคุณสมบัติบางอย่างว่า Flash รองรับโดยเบราว์เซอร์หรือว่าเบราว์เซอร์แสดงภาพหรือไม่หรืออาจเป็นไปได้ว่าคุณต้องการตรวจสอบขนาดหน้าจอ


คุณสามารถพูดคุยเรื่องนี้ได้ในความคิดเห็น อย่างไรก็ตามมีหลายกรณีที่จะตรวจสอบ wevbview
Yozi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.