phát hiện webview trên ipad / iphone qua javascript


91

Có cách nào để phân biệt thông qua javascript nếu trang web chạy bên trong ipad safari hoặc bên trong ứng dụng WebView không?


Đây có phải chỉ dành cho thiết bị iOS không?
Nicolas S

Câu trả lời:


79

Điều này sử dụng kết hợp của window.navigator.userAgentwindow.navigator.standalone. Nó có thể phân biệt giữa tất cả bốn trạng thái liên quan đến ứng dụng web iOS: safari (trình duyệt), độc lập (toàn màn hình), uiwebview và không phải iOS.

Demo: 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 có Safaritrong userAgent. nó thường chạy khác liên quan đến yêu cầu với webcal://giao thức cho các tập tin .ics
neaumusic

@svlada bạn có thể cung cấp thêm thông tin không? Thiết bị của bạn và phiên bản iOS của nó là gì?
sonlexqt

78

Tác nhân người dùng

Chạy trong UIWebView

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

Chạy trong Safari trên 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

Chạy trong Safari trên 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

Chạy trong Chrome trên 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

Chạy trong FireFox trên Mac OS X

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

Mã phát hiện

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);

Có thật không. Tôi không biết tại sao tôi chỉ xem xét cả hai công dụng ngay từ đầu. Cảm ơn câu trả lời của bạn :)
sod

4
Không làm việc trên iPhone 5s / iOS 7, bởi vì cả hai UIWebViewvà Safari có Safaritrong user agent của họ
Razor

@Razor Bạn nói đúng. Thử nghiệm chống lại Versiontrái ngược Safarivới tôi đã làm việc trong iOS mới nhất.
unceus

1
@unceus Bạn có thể vui lòng phác thảo chính xác ý của bạn với Version? Bạn có thay thế Safaribằng Versiontrong var is_uiwebviewdòng?
Henrik Petterson

@HenrikPetterson Đối với các chuỗi tác nhân người dùng, so sánh hai chuỗi tác nhân người dùng đầu tiên ở trên (UIWebView và Safari trên iPad) chuỗi UIWebView chứa 'phiên bản' trong khi chuỗi ipad thì không. Mục tiêu của bạn với việc sửa đổi regex là không rõ ràng và có vẻ như bạn đang tìm kiếm trợ giúp để viết một.
unceus,

10

Tôi nghĩ rằng bạn có thể chỉ cần sử dụng User-Agent.


CẬP NHẬT

Trang được duyệt bằng 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

Tôi sẽ thử trong giây lát với 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

Sự khác biệt là Safari nói Safari/6531.22.7


Giải pháp

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

Vâng, nhưng bạn có bất kỳ ý tưởng nào nếu có một chuỗi cụ thể hoặc thứ gì đó để phát hiện UIWebView trong User-Agent không? Cho đến nay tôi không thể tìm thấy bất cứ điều gì ...
Adam Tal

Đây có phải chỉ dành cho thiết bị iOS không?
Nicolas S

Nicolas những con số sẽ khác nhau vào lúc này vì Safari và UIWebView (và "độc lập" các ứng dụng nhà màn hình web -ie) sử dụng công cụ khác nhau. Điều này thay đổi trong iOS 5.
Ben

Tôi không có nghĩa là các con số, tôi có nghĩa là Safari/.....bản thân là mất tích trong UIWebView
Nicolas S

@Nicolas: khá đúng, xin lỗi tôi đã không chú ý. Tôi tự hỏi liệu có ai có thể xác nhận liệu điều này có còn xảy ra trong iOS5 không?
Ben

7

Vâng:

// 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
Điều này cũng sẽ phù hợp với trình duyệt Safari không chỉ WebView.
Petr Peller

@ThinkingStuff - Ông có thể giúp tôi giúp đỡ diiferentiate giữa Mac OS (trình duyệt máy tính để bàn) và trình duyệt iPad Safari - stackoverflow.com/questions/58344491/...
newdeveloper

5

Tôi đã thử tất cả các giải pháp này nhưng không hiệu quả trong trường hợp của tôi,
tôi sẽ phát hiện Telegram bên trong Webview. Tôi nhận thấy Safari đang thay đổi văn bản kiểu điện thoại thành một liên kết có tiền tố "tel:", vì vậy tôi đã sử dụng điều này để viết mã này, bạn có thể kiểm tra nó: 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
Bạn không nên dựa vào thủ thuật như vậy vì người dùng hoặc bất kỳ nhà phát triển nào khác có thể vô hiệu hóa tính năng phát hiện điện thoại.
Бодров Андрей

@ БодровАндрей Tôi đồng ý với bạn, nhưng đó là cách duy nhất tôi có thể tìm thấy, tôi hy vọng táo cung cấp khác nhau User-Agent cho rằng trong tương lai
Amir Khorsandi

Hãy cẩn thận đây là borken trên iOS 13, vì nếu Chế độ máy tính để bàn được sử dụng thì navigator.platform === 'MacIntel'. Điều này đặc biệt ảnh hưởng đến iPadOS 13 Mobile Safari vì nó sử dụng Chế độ máy tính để bàn theo mặc định.
robocat

@robocat bạn nói đúng. nó bị hỏng trong iOS 13 iPad và tôi hiện đang bị mắc kẹt mà không có giải pháp. Bạn có thể vui lòng giúp tôi với câu hỏi liên quan tại đây stackoverflow.com/questions/58344491/…
newdeveloper

2

Giải pháp của Neoneye không hoạt động nữa (xem nhận xét) và có thể được đơn giản hóa. Mặt khác, chỉ thử nghiệm "Safari" trong UA phản ánh nhiều hơn các thiết bị cầm tay ios.

Đây là bài kiểm tra tôi đang sử dụng:

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

2

Lưu ý rằng phương pháp này không hoạt động đối với iOS 10 và các phiên bản cũ hơn.

Vào mùa xuân năm 2018, không có phương pháp nào được đề xuất phù hợp với tôi vì vậy tôi đã đưa ra một cách tiếp cận mới (không dựa trên 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

Chúng tôi hoan nghênh bạn mở rộng mã cho các thiết bị iPad, tôi nghĩ nó sẽ làm được điều này.

Hoạt động tốt với Telegram, Facebook, VK webviews.


Đối với iPhone X, nó sẽ là 375/812, cũng mới: 414/896 cho iPhone Xs Max / Xr
Oleg Dater

1

Working 15.02.19

Một giải pháp khác để phát hiện các lần xem web trên iOS là kiểm tra sự hỗ trợ / tồn tại của navigator.mediaDevices.

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

Trong trường hợp của tôi, tôi không cần phải bắt tất cả các lần xem web, nhưng những lần xem không hỗ trợ đầu vào máy ảnh / micrô (Lời nhắc: Cảnh báo không kích hoạt trong Chế độ xem web, vì vậy hãy đảm bảo thay đổi một cái gì đó trong dom cho mục đích gỡ lỗi)


0

Tôi biết mã này sẽ kiểm tra xem nó có đang được truy cập từ một biểu tượng được thêm vào màn hình chính hay không:

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

nhưng tôi không chắc nó sẽ phản ứng như thế nào trong UIWebView. Giải pháp khác duy nhất mà tôi có thể nghĩ đến là sử dụng tác nhân người dùng hoặc sử dụng - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationTypevà thay thế chuỗi truy vấn của trang bạn đang truy cập bằng một thứ mà trang sử dụng để xác định rằng nó đang được truy cập từ chế độ xem web.


Cảm ơn, tôi đang sử dụng mã đó, nhưng cần kiểm soát nhiều hơn. Nó dường như chỉ phát hiện chế độ độc lập và coi phần còn lại là Safari.
Adam Tal

0

Sẽ đề xuất sử dụng Modernizr và kiểm tra indexeddb như thế này . Bạn có thể kiểm tra chéo điều đó với cấu hình tác nhân người dùng (thiết bị, hệ điều hành, trình duyệt, v.v.), nhưng phát hiện tính năng thuần túy có vẻ được khuyến khích hơn.


Nghe có vẻ giống như một kế hoạch nhưng bạn sẽ thử nghiệm những tính năng nào? indexeddb là một phần của ie, chrome, firefox, v.v.
SSED

0

Lần trước tôi cần cái này (CHỈ cho mục đích WebView), tôi đã sử dụng kiểm tra này:

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

Điều này bị hỏng trong Chế độ máy tính để bàn iOS13 (nền tảng không còn được đặt thành iPad hoặc iPhone) và trên iPod touch (nền tảng có thể là "iPod" hoặc "iPod touch").
robocat

0

Tôi đã tìm thấy một giải pháp đơn giản để phát hiện iPhone hoặc iPad. Điều này phù hợp với tôi.

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

Thử với 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

Tôi không nghĩ rằng có bất kỳ thứ gì cụ thể nào bạn có thể sử dụng trong Javascript phía máy khách, nhưng nếu bạn có quyền kiểm soát những gì UIWebView gốc có thể làm, bạn có thể muốn xem xét chơi với chuỗi tác nhân người dùng mà nó tạo và thử nghiệm điều đó trong Javascript phía máy khách thay thế? Tôi biết một chút lỗi, nhưng này… Câu hỏi này có thể cung cấp một số gợi ý về cách điều chỉnh tác nhân người dùng:

Thay đổi tác nhân người dùng trong UIWebView (iPhone SDK)


Cảm ơn, Ben. Rất tiếc, tôi không có quyền kiểm soát tác nhân người dùng UIWebView của ứng dụng.
Adam Tal

-7

@ Sod, Tôi không có câu trả lời, nhưng tôi không thuyết phục tại sao bạn muốn kiểm tra, Vì, trình duyệt engine cho dù safari (Trình duyệt) hoặc Ứng dụng của nó sẽ giống như chỉ Webkit của nó, Có Ứng dụng có thể định cấu hình các khả năng của Browser engine như , cho dù ứng dụng muốn chạy JS hay Display Image, v.v.

Tôi tin rằng, bạn phải kiểm tra một số thuộc tính nhất định xem Flash được hỗ trợ bởi Trình duyệt hay trình duyệt có hiển thị hình ảnh hay không, hoặc có thể bạn muốn kiểm tra kích thước màn hình,


bạn có thể thảo luận điều này trong các bình luận. Dù sao cũng có nhiều trường hợp cần kiểm tra wevbview
Yozi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.