Как проверить, поддерживается ли собственный протокол - PullRequest
51 голосов
/ 20 мая 2010

Мы используем программное обеспечение, которое регистрирует собственный протокол. Мы можем запустить приложение из браузера, затем по ссылке, например:

customprotocol://do_this.

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

например:

if (canHandle ('customprotocol')) {
     // run software
}
else {
    // ask to install
}

Редактировать Я знаю о свойстве protocolLong, но оно работает только в IE.

Ответы [ 7 ]

45 голосов
/ 20 мая 2010

К сожалению, нет простого способа достичь этого. Конечно, нет способа заранее определить, установлен ли обработчик протокола.

Internet Explorer , как вы упомянули, обладает свойством protocolLong, но у меня возникают проблемы с его возвратом для всех обработчиков пользовательских протоколов, кроме «Неизвестный протокол» - если кто-нибудь знает, как чтобы IE вернул правильное значение, пожалуйста, дайте мне знать, чтобы я мог обновить этот раздел. Лучшее решение, которое я нашел с IE, это добавить к строке агента пользователя или установить расширение браузера вместе с вашим приложением, которое предоставляет доступное свойство Javascript.

Firefox - безусловно, самый простой из основных браузеров, поскольку он позволит вам попытаться поймать попытку навигации, которая не удалась. Возвращенный объект ошибки содержит свойство name, значение которого NS_ERROR_UNKNOWN_PROTOCOL:

try {
    iframe.contentWindow.location.href = "randomprotocolstring://test/";
} catch(e) {
    if (e.name == "NS_ERROR_UNKNOWN_PROTOCOL")
        window.location = "/download/";
}

Firefox появится со своим собственным окном оповещения:

Firefox не знает, как открыть этот адрес, потому что протокол (randomprotocolstring) не связан ни с одной программой.

Как только вы закроете это окно, блок catch будет выполнен, и у вас будет рабочий запасной вариант.

Вторым является Opera , которая позволяет вам применять законы предсказуемости для определения успешности щелчка по пользовательскому протоколу. Если щелчок настраиваемого протокола работает, страница останется в том же месте. Если обработчик не установлен, Opera перейдет на страницу с ошибкой. Это облегчает обнаружение с помощью iframe:

   iframe.contentWindow.location = "randomprotocolstring://test/";
   window.setTimeout(function () {
       try {
           alert(ifr.contentWindow.location); 
       } catch (e) { window.location = "/download/"; }
   }, 0);

setTimeout здесь, чтобы убедиться, что мы проверяем местоположение после навигации. Важно отметить, что если вы пытаетесь получить доступ к странице, Opera создает исключение ReferenceException (междоменная ошибка безопасности). Это не имеет значения, потому что все, что нам нужно знать, это то, что местоположение изменилось с about:blank, поэтому try...catch работает просто отлично.

Chrome официально отстой в этом отношении. Если обработчик пользовательского протокола завершается неудачно, он делает абсолютно zip. Если обработчик работает ... как вы уже догадались ... он делает абсолютно zip. Боюсь, нет никакой разницы между ними.

Я не тестировал Safari , но боюсь, он будет таким же, как Chrome.

Вы можете попробовать тестовый код , который я написал во время исследования этого (я лично интересовался им). Он совместим с Opera и Firefox, но в настоящее время ничего не делает в IE и Chrome.

11 голосов
/ 07 февраля 2013

Просто чтобы поделиться своим собственным опытом, мы использовали FireBreath, чтобы создать простой кроссплатформенный плагин. После установки этот плагин регистрирует тип MIME, который может быть обнаружен в браузере javascript после обновления страницы. Обнаружение типа MIME указывает, что обработчик протокола установлен.

if(IE) { //This bastard always needs special treatment
    try {
        var flash = new ActiveXObject("Plugin.Name");
    } catch (e) {
        //not installed
    }
else { //firefox,chrome,opera
    navigator.plugins.refresh(true);
    var mimeTypes = navigator.mimeTypes;
    var mime = navigator.mimeTypes['application/x-plugin-name'];
    if(mime) {
        //installed
    } else {
        //not installed
    }
}
7 голосов
/ 01 ноября 2013

Internet Explorer 10 в Windows 8 представил очень полезный метод navigator.msLaunchUri для запуска URL-адреса настраиваемого протокола и определения успеха или неудачи. Например:

        if (typeof (navigator.msLaunchUri) == typeof (Function)) {
            navigator.msLaunchUri(witchUrl,
                function () { /* Success */ },
                function () { /* Failure */ showError(); });

            return;
        }

Windows 7 / IE 9 и ниже поддерживают условные комментарии, как предложено @ mark-kahn.

6 голосов
/ 16 января 2017

Ответ на этот вопрос: установите необычный шрифт во время регистрации своего пользовательского протокола. Затем используйте JavaScript, чтобы проверить, существует ли этот шрифт, используя что-то , например .

Конечно, это взлом, но в отличие от других ответов, он будет работать в браузерах и операционных системах.

4 голосов
/ 07 февраля 2012

Для Internet Explorer лучшее решение, которое я нашел, - это использовать условные комментарии и версию вектора (приложение должно что-то записывать в реестр при установке протокола, см. http://msdn.microsoft.com/en-us/library/ms537512.aspx#Version_Vectors). protocolLong не работает для пользовательского протокола.

3 голосов
/ 12 мая 2012

На мобильном устройстве вы можете использовать встроенный iframe для автоматического переключения между пользовательским протоколом и известным (интернет-магазин или магазин приложений), см. https://gist.github.com/2662899

2 голосов
/ 28 июля 2017

Я просто хочу объяснить больше предыдущего ответа Марка (некоторые люди не поняли, например, user7892745).

1) Когда вы запускаете веб-страницу или веб-приложение, оно проверяет наличие необычного шрифта (что-то вроде китайского шрифта Konfuciuz http://www.fontspace.com/apostrophic-lab/konfuciuz).

Ниже приведен код примера веб-страницы с функцией, которая проверяет шрифт (называется isFontAvailable):

<!DOCTYPE html>
<html>
<head>

</head>
<body>

<script>
/**
* Checks if a font is available to be used on a web page.
*
* @param {String} fontName The name of the font to check
* @return {Boolean}
* @license MIT
* @copyright Sam Clarke 2013
* @author Sam Clarke <sam@samclarke.com>
*/
(function (document) {
   var width;
   var body = document.body;

                    var container = document.createElement('span');
                    container.innerHTML = Array(100).join('wi');
                    container.style.cssText = [
       'position:absolute',
       'width:auto',
       'font-size:128px',
       'left:-99999px'
   ].join(' !important;');

   var getWidth = function (fontFamily) {
       container.style.fontFamily = fontFamily;

       body.appendChild(container);
       width = container.clientWidth;
       body.removeChild(container);

       return width;
   };

   // Pre compute the widths of monospace, serif & sans-serif
   // to improve performance.
   var monoWidth  = getWidth('monospace');
   var serifWidth = getWidth('serif');
   var sansWidth  = getWidth('sans-serif');

   window.isFontAvailable = function (font) {
       return monoWidth !== getWidth(font + ',monospace') ||
           sansWidth !== getWidth(font + ',sans-serif') ||
           serifWidth !== getWidth(font + ',serif');
   };
})(document);



function isProtocolAvailable()
{
    if (isFontAvailable('Konfuciuz')) 
    {
        return true;
    } 
    else 
    {
        return false;
    }
}

function checkProtocolAvail()
{
    if (isProtocolAvailable()) 
    {
        alert('Custom protocol is available!');
    } 
    else 
    {
        alert('Please run executable to install protocol!');
    }
}
</script>

<h3>Check if custom protocol was installed or not</h3>

<pre>


<input type="button" value="Check if custom protocol was installed!" onclick="checkProtocolAvail()">

</body>
</html>

2) Когда пользователь открывает эту страницу в первый раз, шрифт не будет установлен, поэтому он получит сообщение «Пожалуйста, запустите исполняемый файл, чтобы установить собственный протокол ...».

3) Он запустит исполняемый файл, который установит шрифт. Ваш exe-файл может просто скопировать файл шрифта (в моем случае это KONFUC __. Ttf) в каталог C: \ Windows или использовать такой код (пример на Delphi):

// Adding the font ..

AddFontResource(PChar('XXXFont.TTF'));
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);

4) После этого, когда пользователь снова запускает веб-приложение, он получает сообщение «Пользовательский протокол доступен!» сообщение, потому что на этот раз был установлен шрифт.

Протестировано в Google Chrome, Internet Explorer и Firefox - отлично работает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...