mendeteksi ipad / iphone webview melalui javascript

91

Apakah ada cara untuk membedakan melalui javascript jika situs web berjalan di dalam safari ipad atau di dalam aplikasi WebView?

merumput
sumber
Apakah ini hanya untuk perangkat iOS?
Nicolas S

Jawaban:

80

Ini menggunakan kombinasi window.navigator.userAgentdan window.navigator.standalone. Itu dapat membedakan antara keempat status yang berkaitan dengan aplikasi web iOS: safari (browser), mandiri (layar penuh), uiwebview, dan bukan 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
};
ThinkingStiff
sumber
chrome ada Safaridi userAgent. itu berperilaku berbeda sehubungan dengan memerlukan webcal://protokol untuk file .ics
neaumusic
@svlada dapatkah Anda memberikan informasi lebih lanjut? Apa perangkat Anda dan versi iOS-nya?
sonlexqt
Tidak bekerja pada iOS 13 dan 14.
Alex Sorokoletov
78

Agen Pengguna

Berjalan di UIWebView

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

Berjalan di Safari di 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

Berjalan di Safari di 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

Berjalan di Chrome di 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

Berjalan di FireFox di Mac OS X

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

Kode Deteksi

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);
neoneye
sumber
Betulkah. Saya tidak tahu mengapa saya melihat sendiri kedua agen pengguna itu sendiri. Terima kasih atas jawaban Anda :)
sod
4
Tidak berfungsi pada iPhone 5s / iOS 7, karena keduanya UIWebViewdan Safari ada Safaridi agen penggunanya
Razor
@ Razor Anda benar. Pengujian melawan Versionbukannya Safariberhasil untuk saya di iOS terbaru.
unceus
1
@unceus Bisakah Anda menjelaskan dengan tepat apa yang Anda maksud dengan Version? Apakah Anda mengganti Safaridengan Versiondi var is_uiwebviewtelepon?
Henrik Petterson
@HenrikPetterson Berkenaan dengan string agen pengguna, membandingkan dua string agen pengguna pertama di atas (UIWebView, dan Safari di iPad), string UIWebView berisi 'versi' sedangkan yang ipad tidak. Tujuan Anda dengan memodifikasi ekspresi reguler tidak jelas, dan sepertinya Anda mencari bantuan untuk menulisnya.
unceus
10

Saya pikir Anda bisa menggunakan User-Agent.


MEMPERBARUI

Halaman dijelajahi menggunakan 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

Saya akan mencoba sebentar lagi dengan 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

Perbedaannya adalah yang dikatakan Safari Safari/6531.22.7


Larutan

var isSafari = navigator.userAgent.match(/Safari/i) != null;
Nicolas S
sumber
Ya, tapi apakah Anda tahu jika ada string tertentu atau sesuatu untuk mendeteksi UIWebView di User-Agent? Sejauh ini saya tidak dapat menemukan apa pun ...
Adam Tal
Apakah ini hanya untuk perangkat iOS?
Nicolas S
Nicolas angkanya akan berbeda saat ini karena Safari dan UIWebView (dan "stand-alone" —ie home screen — aplikasi web) menggunakan mesin yang berbeda. Ini berubah di iOS 5.
Ben
Saya tidak bermaksud angka, maksud saya Safari/.....itu sendiri hilang di UIWebView
Nicolas S
@Nicolas: benar, maaf saya tidak memperhatikan. Saya ingin tahu apakah ada yang bisa memastikan apakah ini masih terjadi di iOS5?
Ben
7

Ya:

// 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);
John Doherty
sumber
11
Ini juga akan cocok dengan browser Safari tidak hanya WebView.
Petr Peller
@ThinkingStuff - Bisakah Anda membantu saya membantu membedakan antara Mac OS (browser desktop) dan browser Safari iPad - stackoverflow.com/questions/58344491/…
newdeveloper
6

Saya sudah mencoba semua solusi ini tetapi tidak berhasil dalam kasus saya,
saya akan mendeteksi Telegram di dalam Webview. Saya perhatikan Safari mengubah teks gaya ponsel menjadi tautan dengan awalan "tel:", jadi saya telah menggunakan ini untuk menulis kode ini, Anda dapat mengujinya: 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>
Amir Khorsandi
sumber
1
Anda tidak boleh mengandalkan trik seperti itu karena pengguna atau pengembang lain dapat menonaktifkan deteksi telepon.
Бодров Андрей
@ БодровАндрей Saya setuju dengan Anda, tetapi itulah satu-satunya cara yang dapat saya temukan, saya harap apple menyediakan Agen-Pengguna yang berbeda untuk itu di masa mendatang
Amir Khorsandi
Hati-hati ini terjadi di iOS 13, karena jika Mode Desktop digunakan, maka navigator.platform === 'MacIntel'. Ini terutama memengaruhi Safari Seluler iPadOS 13 karena menggunakan Mode Desktop secara default.
robocat
@robocat Anda benar. yang rusak di iOS 13 iPad dan saya sekarang terjebak tanpa solusi. Bisakah Anda membantu saya dengan pertanyaan terkait di sini stackoverflow.com/questions/58344491/…
newdeveloper
Ini berfungsi pada iOS 14
Alex Sorokoletov
2

Solusi Neoneye tidak berfungsi lagi (lihat komentar) dan dapat disederhanakan. Di sisi lain, hanya menguji "Safari" di alamat UA jauh lebih banyak daripada perangkat genggam ios.

Ini adalah tes yang saya gunakan:

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

Perhatikan bahwa pendekatan ini tidak berfungsi untuk iOS 10 dan versi yang lebih lama.

Untuk Musim Semi 2018 tidak ada metode yang diusulkan yang berhasil untuk saya, jadi saya datang dengan pendekatan baru (yang bukan berbasis 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

Anda dipersilakan untuk memperpanjang kode untuk perangkat iPad juga, saya pikir itu harus berhasil.

Bekerja dengan baik untuk tampilan web Telegram, Facebook, VK.

Boris Chumichev
sumber
Untuk iPhone X akan menjadi 375/812, juga baru: 414/896 untuk iPhone Xs Max / Xr
Oleg Dater
1

Working 15.02.19

Solusi lain untuk mendeteksi tampilan web di iOS adalah memeriksa dukungan / keberadaan navigator.mediaDevices.

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

Dalam kasus saya, saya tidak perlu menangkap semua tampilan web, tetapi yang tidak mendukung input kamera / mikrofon (Pengingat: Peringatan tidak terpicu di Webview, jadi pastikan untuk mengubah sesuatu di dom untuk tujuan debug)

vinni
sumber
0

Saya tahu kode ini akan memeriksa apakah sedang diakses dari ikon yang ditambahkan ke layar beranda:

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

tapi saya tidak yakin bagaimana reaksinya di UIWebView. Satu-satunya solusi lain yang dapat saya pikirkan adalah mendapatkan agen pengguna atau menggunakan - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationTypedan mengganti string kueri dari halaman yang Anda akses dengan sesuatu yang digunakan halaman untuk mengidentifikasi bahwa itu sedang diakses dari tampilan web.

Preston
sumber
Terima kasih, saya menggunakan kode itu, tetapi perlu lebih banyak kontrol. Tampaknya hanya mendeteksi mode mandiri, dan menganggap sisanya sebagai Safari.
Adam Tal
0

Sarankan menggunakan Modernizr , dan memeriksa indexeddb seperti ini . Anda dapat memeriksa ulang itu dengan konfigurasi agen pengguna (perangkat, OS, browser, dll), tetapi deteksi fitur murni tampaknya lebih disarankan.

jiku
sumber
Kedengarannya seperti rencana, tetapi fitur apa yang akan Anda uji? indexeddb adalah bagian dari ie, chrome, firefox dll
SSED
0

Terakhir kali saya membutuhkan ini (HANYA untuk tujuan WebView), saya menggunakan pemeriksaan ini:

function isIOS() {
     return !/safari/.test( window.navigator.userAgent.toLowerCase()) || navigator.platform === 'iOS' || navigator.platform === 'iPhone';
}
CatalinBerta
sumber
Ini rusak dalam Mode Desktop iOS13 (platform tidak lagi disetel ke iPad atau iPhone), dan di iPod touch (platform dapat berupa "iPod" atau "iPod touch").
robocat
0

Saya telah menemukan solusi sederhana untuk mendeteksi iPhone atau iPad. Ini bekerja untuk saya dengan baik.

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
    }
Vijay Dhanvai
sumber
0

Coba Dengan 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)
Mahmoud D. Alghraibeh
sumber
-2

Saya tidak berpikir ada sesuatu yang spesifik yang dapat Anda gunakan dalam Javascript sisi klien, tetapi jika Anda memiliki kontrol atas apa yang dapat dilakukan UIWebView yang berasal, Anda mungkin ingin mempertimbangkan untuk bermain dengan string agen pengguna yang dihasilkannya, dan mengujinya di Javascript sisi klien? Sedikit retasan yang saya tahu, tapi hei… Pertanyaan ini mungkin memberikan beberapa petunjuk tentang cara menyesuaikan agen pengguna:

Ubah Agen Pengguna di UIWebView (iPhone SDK)

Ben
sumber
Terima kasih, Ben. Sayangnya, saya tidak memiliki kendali atas agen pengguna UIWebView aplikasi.
Adam Tal
-7

@ Sod, Saya tidak punya jawaban, tapi saya tidak yakin mengapa Anda ingin memeriksa, Karena, mesin browser apakah safari (Browser) atau Aplikasi akan sama dengan Webkit-nya saja, Ya Aplikasi dapat mengkonfigurasi kemampuan mesin Browser seperti , apakah aplikasi ingin menjalankan JS atau Display Image dll…

Saya yakin, Anda harus memeriksa properti tertentu apakah Flash didukung oleh Browser atau apakah browser menampilkan gambar atau tidak, atau mungkin Anda ingin memeriksa ukuran layar,

Amitg2k12
sumber
Anda bisa mendiskusikan ini di komentar. Pokoknya ada banyak kasus untuk memeriksa wevbview
Yozi