Как определить обработчики протоколов браузера? - PullRequest
76 голосов
/ 08 мая 2009

Я создал собственный обработчик протокола URL.

http://

mailto://

custom://

Я зарегистрировал приложение WinForms, чтобы отвечать соответствующим образом. Все это прекрасно работает.

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

Для того, чтобы сделать это, мне нужно иметь возможность обнаруживать зарегистрированные обработчики протоколов браузера, я бы предположил из JavaScript. Но я не смог найти способ опроса информации. Я надеюсь найти решение этой проблемы.

Спасибо за любые идеи, которыми вы могли бы поделиться.

Ответы [ 15 ]

32 голосов
/ 08 мая 2009

Это будет очень , очень хаки способ сделать это ... но будет ли это работать?

  • Поставь ссылку как обычно ...
  • Но прикрепите к нему обработчик onclick, который устанавливает таймер и добавляет обработчик onblur для окна
  • (в теории), если браузер обрабатывает ссылку (приложение X) загрузит кражу фокуса из окна ...
  • Если сработало событие onblur, очистить таймер ...
  • В противном случае в течение 3-5 секунд дайте своему таймауту сработать ... и оповестите пользователя "Хм, похоже, у вас не установлено Mega Uber Cool Application ... вы хотите установить его сейчас? (Хорошо) ( Отменить) "

Далеко не пуленепробиваемый ... но это может помочь?

17 голосов
/ 15 сентября 2012

Нет замечательного кросс-браузерного способа сделать это. В IE10 + на Win8 + новый msLaunchUri API позволяет запускать протокол, например так:

navigator.msLaunchUri('skype:123456', 
  function() 
  { 
    alert('success');
  }, 
  function()
  {
    alert('failed');
  } 
); 

Если протокол не установлен, сработает обратный вызов сбоя. В противном случае протокол запустится и сработает обратный вызов.

Я обсуждаю эту тему чуть дальше: http://blogs.msdn.com/b/ieinternals/archive/2011/07/14/url-protocols-application-protocols-and-asynchronous-pluggable-protocols-oh-my.aspx

16 голосов
/ 25 апреля 2011

HTML5 определяет Пользовательские схемы и обработчики содержимого (насколько мне известно, Firefox пока является единственным разработчиком ), но, к сожалению, в настоящее время нет способа проверить, существует ли обработчик - было предложено , но никаких последующих действий не было. Это кажется критически важным для эффективного использования пользовательских обработчиков, и мы, как разработчики, должны обратить внимание на эту проблему, чтобы реализовать ее.

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

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

13 голосов
/ 06 ноября 2009

Похоже, что через javascript нет простого способа обнаружить наличие установленного приложения, в котором зарегистрирован обработчик протокола.

В модели iTunes Apple предоставляет URL-адреса своим серверам, которые затем предоставляют страницы, на которых выполняется некоторый JavaScript:

http://ax.itunes.apple.com/detection/itmsCheck.js

Таким образом, установщик iTunes, по-видимому, развертывает плагины для основных браузеров, присутствие которых затем можно обнаружить.

Если ваш плагин установлен, то вы можете быть уверены, что перенаправление на URL-адрес вашего приложения будет успешным.

9 голосов
/ 24 января 2010

Какое самое простое решение - спросить пользователя с первого раза.

Использование диалога подтверждения Javascript для каждого примера:

You need this software to be able to read this link. Did you install it ?

if yes: create a cookie to not ask next time; return false and the link applies
if false: window.location.href = '/downloadpage/'
5 голосов
/ 21 июня 2015

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

https://github.com/ismailhabib/custom-protocol-detection

5 голосов
/ 26 апреля 2012

Если у вас есть контроль над программой, которую вы пытаетесь запустить (код), одним из способов проверить, успешно ли пользователь запустил приложение, будет:

  1. Прежде чем пытаться открыть пользовательский протокол, сделайте AJAX-запрос к серверному сценарию, который сохраняет намерения пользователя в базе данных (например, сохраните идентификатор пользователя и то, что он хотел сделать).

  2. Попробуйте открыть программу и передать данные о намерениях.

  3. Пусть программа отправит серверу запрос на удаление записи в базе данных (используя данные намерения для поиска правильной строки).

  4. Заставьте javascript некоторое время опрашивать сервер, чтобы узнать, не исчезла ли запись в базе данных. Если запись пропала, вы узнаете, что пользователь успешно открыл приложение, в противном случае запись останется (вы можете удалить ее позже с помощью cronjob).

Я не пробовал этот метод, просто подумал.

4 голосов
/ 27 февраля 2014

Мне удалось наконец получить кросс-браузерное решение (Chrome 32, Firefox 27, IE 11, Safari 6), работающее с комбинацией this и супер-простым расширением Safari. Большая часть этого решения так или иначе упоминается в этом и этом другом вопросе .

Вот сценарий:

function launchCustomProtocol(elem, url, callback) {
    var iframe, myWindow, success = false;

    if (Browser.name === "Internet Explorer") {
        myWindow = window.open('', '', 'width=0,height=0');
        myWindow.document.write("<iframe src='" + url + "'></iframe>");

        setTimeout(function () {
            try {
                myWindow.location.href;
                success = true;
            } catch (ex) {
                console.log(ex);
            }

            if (success) {
                myWindow.setTimeout('window.close()', 100);
            } else {
                myWindow.close();
            }

            callback(success);
        }, 100);
    } else if (Browser.name === "Firefox") {
        try {
            iframe = $("<iframe />");
            iframe.css({"display": "none"});
            iframe.appendTo("body");
            iframe[0].contentWindow.location.href = url;

            success = true;
        } catch (ex) {
            success = false;
        }

        iframe.remove();

        callback(success);
    } else if (Browser.name === "Chrome") {
        elem.css({"outline": 0});
        elem.attr("tabindex", "1");
        elem.focus();

        elem.blur(function () {
            success = true;
            callback(true);  // true
        });

        location.href = url;

        setTimeout(function () {
            elem.off('blur');
            elem.removeAttr("tabindex");

            if (!success) {
                callback(false);  // false
            }
        }, 1000);
    } else if (Browser.name === "Safari") {
        if (myappinstalledflag) {
            location.href = url;
            success = true;
        } else {
            success = false;
        }

        callback(success);
    }
}

Расширение Safari было легко реализовать. Он состоял из одной строки сценария внедрения:

myinject.js:

window.postMessage("myappinstalled", window.location.origin);

Затем на веб-странице JavaScript необходимо сначала зарегистрировать событие сообщения и установить флаг, если сообщение получено:

window.addEventListener('message', function (msg) {
    if (msg.data === "myappinstalled") {
        myappinstalledflag = true;
    }
}, false);

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

Во всех случаях, если обратный вызов возвращает false, вы знаете, чтобы сообщить пользователю, что приложение (т. Е. Его собственный протокол) не установлено.

4 голосов
/ 11 мая 2010

Вы можете попробовать что-то вроде этого:

function OpenCustomLink(link) {

    var w = window.open(link, 'xyz', 'status=0,toolbar=0,menubar=0,height=0,width=0,top=-10,left=-10');
    if(w == null) {            
        //Work Fine
    }
    else {
        w.close();
        if (confirm('You Need a Custom Program. Do you want to install?')) {
            window.location = 'SetupCustomProtocol.exe'; //URL for installer
        }
    }
}
...