Определите, перемещался ли пользователь с мобильного Safari - PullRequest
52 голосов
/ 09 июня 2010

У меня есть приложение, и я хотел бы перенаправить пользователей на разные страницы в зависимости от того, откуда они переходят.

При переходе из веб-клипа не перенаправляйте.При навигации с мобильного Safari, перенаправьте на safari.aspx.При навигации из любого места перенаправьте на unavailable.aspx

Я смог использовать iPhone WebApps, есть ли способ определить, как он был загружен?Домашний экран против Safari? , чтобы определить, переходил ли пользователь с веб-клипа, но у меня возникают проблемы с определением, переходил ли пользователь с мобильного Safari на iPhone или iPod.

Вот что у меня есть:

if (window.navigator.standalone) {
    // user navigated from web clip, don't redirect
}
else if (/*logic for mobile Safari*/) {
    //user navigated from mobile Safari, redirect to safari page
    window.location = "safari.aspx";
}
else {
    //user navigated from some other browser, redirect to unavailable page
    window.location = "unavailable.aspx";
}

Ответы [ 11 ]

125 голосов
/ 17 апреля 2015

См. https://developer.chrome.com/multidevice/user-agent#chrome_for_ios_user_agent - строки пользовательского агента для Safari на iOS и для Chrome на iOS неудобно похожи:

Chrome

Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3

Safari

Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543 Safari/419.3

Похоже, лучший подход здесь - сначала проверить iOS, как предложили другие ответы, а затем отфильтроватьо том, что делает Safari UA уникальным, что я бы посоветовал сделать лучше всего с помощью «это AppleWebKit, а не CriOS»:

var ua = window.navigator.userAgent;
var iOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i);
var webkit = !!ua.match(/WebKit/i);
var iOSSafari = iOS && webkit && !ua.match(/CriOS/i);
26 голосов
/ 08 февраля 2011

Лучшая практика:

function isMobileSafari() {
    return navigator.userAgent.match(/(iPod|iPhone|iPad)/) && navigator.userAgent.match(/AppleWebKit/)
}
21 голосов
/ 09 июня 2010

ОБНОВЛЕНИЕ : Это очень старый ответ, и я не могу удалить его, потому что ответ принят.Проверьте unwitting ответ ниже для лучшего решения.


Вы должны быть в состоянии проверить подстроку "iPad" или "iPhone" в агент пользователя строка:

var userAgent = window.navigator.userAgent;

if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i)) {
   // iPad or iPhone
}
else {
   // Anything else
}
5 голосов
/ 17 декабря 2015

Падающий код находит только мобильное сафари и ничего больше (кроме дельфина и других небольших браузеров)

  (/(iPad|iPhone|iPod)/gi).test(userAgent) &&
  !(/CriOS/).test(userAgent) &&
  !(/FxiOS/).test(userAgent) &&
  !(/OPiOS/).test(userAgent) &&
  !(/mercury/).test(userAgent)
3 голосов
/ 05 марта 2016

Объединены все ответы и комментарии.И это результат.

function iOSSafari(userAgent)
{
    return /iP(ad|od|hone)/i.test(userAgent) && /WebKit/i.test(userAgent) && !(/(CriOS|FxiOS|OPiOS|mercury)/i.test(userAgent));
}



var iOSSafari = /iP(ad|od|hone)/i.test(window.navigator.userAgent) && /WebKit/i.test(window.navigator.userAgent) && !(/(CriOS|FxiOS|OPiOS|mercury)/i.test(window.navigator.userAgent));
2 голосов
/ 29 сентября 2016

Видя все ответы, вот несколько советов о предлагаемых RegExes:

  • AppleWebKit соответствует Desktop Safari тоже (не только для мобильных устройств)
  • не нужно звонить .match более одного раза для таких простых регулярных выражений и предпочитают более легкий .test метод.
  • g (глобальный) флаг регулярного выражения бесполезен, в то время как i (без учета регистра) может быть полезным
  • нет необходимости в захвате (в скобках), мы просто тестируем строку

Я просто использую это, поскольку получение true для мобильного Chrome для меня нормально (то же поведение):

/iPhone|iPad|iPod/i.test(navigator.userAgent)

(я просто хочу определить, является ли устройство целевым для приложения для iOS)

1 голос
/ 10 февраля 2017

Я проголосовал за ответ @unwitting, так как это неизбежно привело меня в движение.Однако при рендеринге моего SPA в веб-представлении iOS мне нужно было немного его настроить.

function is_iOS () {
    /*
        Returns whether device agent is iOS Safari
    */
    var ua = navigator.userAgent;
    var iOS = !!ua.match(/iPad/i) || !!ua.match(/iPhone/i);
    var webkitUa = !!ua.match(/WebKit/i);

    return typeof webkit !== 'undefined' && iOS && webkit && !ua.match(/CriOS/i);
};

Основным отличием является переименование webkit в webkitUa, чтобы предотвратить конфликт с корневым объектом webkit, используемым в качестве обработчика сообщений между SPA и UIView.

1 голос
/ 11 марта 2014

На самом деле, нет серебряной пули обнаружения мобильных сафари.Существует довольно много браузеров, которые могут использовать ключевые слова пользовательского агента мобильного сафари.Может быть, вы можете попробовать обнаружение функций и продолжать обновлять правило.

0 голосов
/ 21 марта 2018

Я искал этот ответ и вспомнил, что сталкивался с этим раньше.

Самый надежный способ обнаружения Safari на iOS в JavaScript - это

if (window.outerWidth === 0) {
    // Code for Safari on iOS
} 

or 

if (window.outerHeight === 0) {
    // Code for Safari on iOS
} 

. По некоторым причинам Safari на iOS возвращает 0 для свойства window.outerHeight и свойства window.outerWidth.

Это для всех iPad и iPhone во всех версиях iOS.У всех других браузеров и устройств это свойство работает нормально.

Не уверен, намерены ли они изменить это, но пока оно работает хорошо.

0 голосов
/ 23 сентября 2017

Я знаю, что это старая ветка, но я хотел бы поделиться своим решением с вами, ребята.

Мне нужно было определить, когда пользователь перемещается из Desktop Safari (поскольку мы находимся в середине 2017 года, и Apple не оказывает никакой поддержки для input[type="date"] YET ...

Итак, я сделал запасной пользовательский указатель даты). Но применимо только к сафари в настольных системах, потому что этот тип ввода отлично работает в мобильном Safari. Итак, я сделал это Regex, чтобы обнаруживать только настольный Safari. Я уже тестировал его, и он не совпадает с Opera, Chrome, Firefox или Safari Mobile.

Надеюсь, это поможет некоторым из вас, ребята.

if(userAgent.match(/^(?!.*chrome).(?!.*mobile).(?!.*firefox).(?!.*iPad).(?!.*iPhone).*safari.*$/i)){
  $('input[type="date"]').each(function(){
    $(this).BitmallDatePicker();
  })
}
...