Как стать автором
Обновить

Комментарии 17

Вы используете jQuery, почему бы тогда для проверки браузера не использовать $.browser? Как ни как упрощает код на таких мелочах. Мое ИМХО, если использовать что-то в проекте, то на 100%.
Потому что, начиная с версии 1.9:

This property was removed in jQuery 1.9 and is available only through the jQuery.migrate plugin. Please try to use feature detection instead.


(jQuery в примере используется только для уменьшения объема кода)
В jQuery 1.9, например, $.browser уже нет. В качестве альтернативы можно использовать Modernizr.
Не существует — значит не существует. Ни один браузер пока не реализовал этот стандарт.
Кроме того, этот стандарт позволяет регистрировать в качестве обработчиков URL Scheme только веб-приложения, но не локальные. А это большая разница.
Статья в блоге разработчиков Opera начинается с того, что они это реализовали у себя. Еще спецификация по сему делу не позволяет печь пирожки и заваривать кофеек, вот только вы не об этом у себя писали, а о том, что нет возможности определить зарегистрирована ли определенная URL Scheme в браузере, аль нет, а это как раз спека и описывает. Ну да ладно, буквоедством заниматься нет желания, я лишь указал на возможное решение, ибо у вас все равно для той же Opera отдельное решение.
Я на досуге проверю в Opera, может ли isProtocolHandlerRegistered() определить схемы, зарегистрированные локальными приложениями, или же она определяет только схемы, зарегистрированные с помощью registerProtocolHandler(). Если может, внесу в статью еще один вариант для Opera, раз уж они впереди планеты всей.
Проверил isProtocolHandlerRegistered(). Функция проверяет, зарегистрирован ли конкретный URL как обработчик протокола (название функции говорит само за себя — функция проверяет именно обработчик протокола, а не сам протокол). Например, если зарегистрировать собственный протокол вот таким образом:

navigator.registerProtocolHandler('web+myproto', 'http://mysite.com/?uri=%s', 'My Proto');

то потом можно сделать вот так:

navigator.isProtocolHandlerRegistered('web+myproto', 'http://mysite.com/?uri=%s');

и получить в ответ 'registered'. Но если сделать вот так:

navigator.isProtocolHandlerRegistered('web+myproto', null);

получим 'undefined'.

Так что придется пока довольствоваться костылями, предложенными в этой статье.

И еще момент, раз уж заговорили об этом. Зарегистрировать собственный протокол без префикса 'web+' тоже нельзя. Можно только повесить свой обработчик на уже зарегистрированные протоколы (так называемые whitelisted schemes, например: mailto, ssh, tel). Это значит, что зарегистрировать, скажем, протокол 'myproto' через registerProtocolHandler не получится.

Но есть и хорошая новость. Стандарт поддерживает уже не только Opera, но и последние версии Chrome и Firefox. Так что, если кому эта фича полезна, уже вполне можно пользоваться.
Я столкнулся с такой же задачей, нашел вот такие костыли www.rajeshsegu.com/2012/09/browser-detect-custom-protocols/comment-page-1/. Интересно продвинулись ли вы с тех пор в этом направлении? Огорчают всплывающие алерты, хотелось бы чтобы проверка проходила молча.
Спасибо за ссылку, есть полезные моменты там. Что касается алертов «supported => true/false», то они гасятся в 28 строке их кода:

alert(getProtocol() + " supported => " + isSupported);

В остальном — те же проблемы. Например, благодаря try...catch в Firefox и Opera есть возможность провести 100% проверку и все корректно обработать. А вот в Chrome всегда будут негативные срабатывания, особенно при первой проверке или перегруженной памяти. При чем, если протокол зарегистрирован, то приложение успешно стартанет в конечном итоге. Но ветка false уже пойдет на выполнение, и будет некрасиво. Ну и главная проблема — нельзя просто проверить наличие протокола (в отличие от web-handlers). Сделать можно только проверку боем, попытавшись открыть ссылку/загрузить фрейм. Мне, по крайней мере, других решений не попадалось.
Да опера и лиса радуют — 100% проверка, еще сто процентов на IE10+ метод msLaunchUri (не реализован в версии под windows 7 — емае!), можно добиться 100% на всех ослах, если включить эмуляцию IE8 (начиная с 10 версии условные комментарии не работают — рука-лицо) и прописать Version Vectors в реестре инсталлером, а условным каментом можно проверить наличие ключа.

Насколько я понял проверка в сафари и хроме основана на событиях фокуса, что конечно печально.

Под алертами я имел ввиду, что для проверки надо попытаться открыть ссылку — и получить запрос на разрешение, соотв. это нельзя делать при загрузке страницы, например, только по нажатию на ссылку.
Все верно. Поэтому для себя я сделал выбор — убрал все эти костыли и оставил на форме обе кнопки — маленькую серую на установку приложения и большую зеленую на запуск + краткий вступительный комментарий. В моем сценарии это лучше, чем вводить пользователей в ступор странным поведением программы, в попытках сделать их жизнь проще. В других сценариях, к сожалению, приходится извращаться.
Отказались в итоге от прямолинейной проверки, прилага после запуска отправляет подтверждение через сервер в браузерный клиент. Решение конечно не 100% надежное, но лучше чем яваскриптовые костыли…

Был еще один способ это сделать — флешовый LocalConnection(у нас прилага на Аире и клиент на Флексе), но хромой и тут нагадил, у него флешплеер в сендбоксе, не разрешает…

Плюс производители браузеров задепрекейтили единственный кроссплатформенный и кроссбраузерный API — NPAPI, можно было написать болваночку плагина и проверять его в яваскрипте. Фактически не оставили ни одного вменяемого варианта.

Т.о. майкрасофт продвигает, добавил даже msLaunchUri, а остальные под предлогом безопасности ничего не сделали, а оставили так как есть (в том числе и с дырами).
Тоже вариант. Но опять придется ловить вменяемый таймаут ожидания сообщения от проги, чтобы на медленных компах не уйти на false раньше времени. Но тут хоть нет проблемы, что кто-нибудь руками фокус уведет из браузера за время таймаута. Так, глядишь, и скоро выйдем на вполне приемлемое решение :)
В мобильных браузерах тесты не проводились, но вариант с таймаутом вполне может оказаться работоспособным на Android и iOS.
За Android не скажу, а в iOS есть Smart App Banners.

В разделе <head> вставляете тег с айди приложения и параметрами для него:

<meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL">

Safari показывает над содержимым страницы такой баннер:
пример Smart App Banner

Если приложение установлено, то по нажатию на кнопку «Open» оно запустится с переданными параметрами.
Если приложение не установлено, то кнопка будет называться «View», и по тапу откроется его страница в App Store.

При этом баннер совершенно не мешает и ничего не закрывает, при скроллинге он уходит вверх за край экрана, как часть страницы.
Странно, что на Хабре это до сих пор не поддерживается при наличии официального приложения.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории