определить ipad / iphone webview через javascript


91

Есть ли способ отличаться через javascript, если веб-сайт работает внутри ipad safari или внутри приложения 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.
Алексей Сороколетов

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

В самом деле. Я не знаю, почему я просто посмотрел на оба агента пользователя в первую очередь. Спасибо за ответ :)
дерьмо

4
Не работает на iPhone 5s / iOS 7, потому что у обоих UIWebViewи Safari есть Safariпользовательский агент
Razor,

@Razor Ты прав. Тестирование против, Versionа не Safariработало для меня в последней версии iOS.
unceus

1
@unceus Не могли бы вы описать, что именно вы имеете в виду Version? Есть ли заменить Safariс Versionв var is_uiwebviewлинии?
Хенрик Петтерсон

@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? Пока ничего не нашел ...
Адам Тал

Это только для устройств iOS?
Nicolas S

Nicolas цифра будет отличаться в данный момент , так как Safari и UIWebView (и «автономный» -ie дома экрана веб - приложения) используют различные двигатели. Это изменится в iOS 5.
Бен,

Я не имею в виду числа, я имею в виду, что Safari/.....сам по себе отсутствует в UIWebView
Nicolas S

@Nicolas: совершенно верно, извини, я не обратил внимания. Интересно, может ли кто-нибудь подтвердить, так ли это до сих пор в 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.
Петр Пеллер

@ThinkingStuff - Не могли бы вы помочь мне разобраться между Mac OS (настольный браузер) и браузером iPad Safari - 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
Не стоит полагаться на такую ​​уловку, потому что пользователь или любой другой разработчик может отключить обнаружение телефона.
Бодров Андрей

@ БодровАндрей Я согласен с вами, но это был единственный способ найти, я надеюсь, что Apple предоставит другой User-Agent для этого в будущем
Амир Хорсанди

Остерегайтесь этого в iOS 13, потому что, если используется режим рабочего стола navigator.platform === 'MacIntel'. Это особенно касается iPadOS 13 Mobile Safari, поскольку по умолчанию он использует режим рабочего стола.
robocat

@robocat, ты прав. он сломан в iOS 13 iPad, и я сейчас застрял без решения. Не могли бы вы помочь мне со связанным вопросом здесь stackoverflow.com/questions/58344491/…
newdeveloper

Это работает на iOS 14
Алексей Сороколетов

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, ВКонтакте.


Для iPhone X это будет 375/812, также новинка: 414/896 для iPhone Xs Max / Xr
Олег Датер

1

Working 15.02.19

Еще одно решение для обнаружения веб-просмотров на iOS - проверка поддержки / существования navigator.mediaDevices.

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

В моем случае мне не нужно было ловить все веб-просмотры, но те, которые не поддерживают ввод камеры / микрофона (напоминание: оповещения не запускаются в веб-просмотре, поэтому обязательно измените что-то в 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 вместо этого? Я знаю, что это немного взлома, но эй ... Этот вопрос может дать некоторые подсказки по настройке пользовательского агента:

Изменить пользовательский агент в UIWebView (iPhone SDK)


Спасибо, Бен. К сожалению, у меня нет контроля над пользовательским агентом UIWebView приложения.
Adam Tal

-7

@ Дерьмо, у меня нет ответа, но я не уверен, почему вы хотите проверить, Поскольку движок браузера будет ли его сафари (браузер) или приложение таким же, как его только Webkit, Да, приложение может настроить возможности движка браузера, например , хочет ли приложение запускать JS или Display Image и т. д.

Я считаю, что вы должны проверить определенное свойство, поддерживает ли Flash браузер, отображает ли браузер изображение или нет, или, возможно, вы хотите проверить размер экрана,


вы можете обсудить это в комментариях. В любом случае есть много случаев, чтобы проверить wevbview
Йози
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.