wake-up-neo.com

Wie erkennt man die Protokollhandler des Browsers?

Ich habe einen benutzerdefinierten URL-Protokollhandler erstellt.

http://

mailto://

custom://

Ich habe eine WinForms-Anwendung registriert, um entsprechend zu antworten. Das alles funktioniert super.

Ich möchte jedoch in der Lage sein, den Fall, in dem der Benutzer noch keinen benutzerdefinierten URL-Protokoll-Handler installiert hat, zügig zu behandeln.

Um dies tun zu können, muss ich in der Lage sein, die registrierten Protokoll-Handler des Browsers zu erkennen, würde ich von JavaScript ausgehen. Ich habe jedoch keinen Weg gefunden, die Informationen abzufragen. Ich hoffe, eine Lösung für dieses Problem zu finden.

Vielen Dank für Ihre Ideen.

74
Chris Craft

Dies wäre ein sehr, sehr hackyWeg, dies zu tun ... aber würde das funktionieren?

  • Setzen Sie den Link wie gewohnt ein ...
  • Fügen Sie jedoch einen Onclick-Handler hinzu, der einen Timer festlegt und einen Onblur-Handler für das Fenster hinzufügt
  • (theoretisch) Wenn der Browser den Link (Anwendung X) verarbeitet, wird der Fokus aus dem Fenster gestohlen ...
  • Wenn das Onblur-Ereignis ausgelöst wird, löschen Sie den Timer ...
  • Andernfalls lassen Sie Ihr Timeout in 3-5 Sekunden feuern ... und benachrichtigen Sie den Benutzer "Hmm, es scheint, als hätten Sie die Mega Uber Cool-Anwendung nicht installiert ... Möchten Sie sie jetzt installieren? (Ok)

Weit davon entfernt, kugelsicher zu sein ... aber es könnte helfen?

31
scunliffe

Es gibt keine großartige Cross-Browser-Methode, um dies zu tun. In IE10 + unter Win8 + können Sie mit einer neuen msLaunchUri-API ein Protokoll starten, z.

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

Wenn das Protokoll nicht installiert ist, wird der Fehlerrückruf ausgelöst. Andernfalls wird das Protokoll gestartet und der Erfolgsrückruf ausgelöst.

Ich diskutiere dieses Thema hier ein wenig weiter: http://blogs.msdn.com/b/ieinternals/archive/2011/07/14/url-protocols-application-protocols-and-asynchronousplugable- Protokolle-oh-my.aspx

17
EricLaw

HTML5 definiert Custom Schema- und Content-Handler (meines Wissens ist Firefox bisher der einzige Implementor ), aber leider gibt es zurzeit keine Möglichkeit zu überprüfen, ob ein Handler bereits existiert - er wurde vorgeschlagen , aber es gab kein Follow-up. Dies scheint eine wichtige Funktion für die effektive Verwendung benutzerdefinierter Handler zu sein, und wir als Entwickler sollten auf dieses Problem aufmerksam machen, um es implementieren zu können.

16
Hugh Guiney

Sie können einen eingebetteten Iframe verwenden, um automatisch zwischen dem benutzerdefinierten und einem bekannten Protokoll (Web- oder App-Store) umzuschalten, siehe https://Gist.github.com/2662899 .

13
David W. Keith

Es scheint keinen einfachen Weg über Javascript zu geben, um festzustellen, ob eine installierte App einen Protokollhandler registriert hat.

Im iTunes-Modell stellt Apple den Servern URLs zur Verfügung, auf denen dann Seiten mit Javascript angezeigt werden:

http://ax.iTunes.Apple.com/detection/itmsCheck.js

Das iTunes-Installationsprogramm stellt also anscheinend Plugins für die wichtigsten Browser bereit, deren Anwesenheit dann erkannt werden kann.

Wenn Ihr Plugin installiert ist, können Sie ziemlich sicher sein, dass die Umleitung auf Ihre app-spezifische URL erfolgreich ist.

13
jtomson

Die einfachste Lösung ist, den Benutzer beim ersten Mal zu fragen. 

Verwenden Sie ein Javascript-Bestätigungsdialogfeld gemäß Beispiel:

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/'
9
Natim

Ich habe eine generische Bibliothek für dieses Problem erstellt, basierend auf der Annahme, dass der benutzerdefinierte Protokoll-Handler ein neues Fenster auslöst, um den Fokus aus dem Browser herauszunehmen.

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

5
habsq

Wenn Sie die Kontrolle über das Programm haben, das Sie ausführen möchten (den Code), können Sie beispielsweise feststellen, ob der Benutzer die Anwendung erfolgreich ausgeführt hat:

  1. Bevor Sie versuchen, das benutzerdefinierte Protokoll zu öffnen, stellen Sie eine AJAX - Anforderung an ein Serverskript, das die Absicht des Benutzers in einer Datenbank speichert (speichern Sie beispielsweise die Benutzer-ID und was sie tun wollte).

  2. Versuchen Sie, das Programm zu öffnen, und geben Sie die Absichtsdaten weiter.

  3. Bitten Sie das Programm, eine Anforderung an den Server zu senden, um den Datenbankeintrag zu entfernen (verwenden Sie die Absichtsdaten, um die richtige Zeile zu finden).

  4. Stellen Sie sicher, dass der Javascript für eine Weile vom Server abgefragt wird, um zu sehen, ob der Datenbankeintrag verschwunden ist. Wenn der Eintrag nicht mehr vorhanden ist, wissen Sie, dass der Benutzer die Anwendung erfolgreich geöffnet hat. Andernfalls bleibt der Eintrag erhalten (Sie können ihn später mit cronjob entfernen).

Ich habe diese Methode nicht ausprobiert, nur gedacht.

5
quano

Ich konnte endlich eine Browser-übergreifende Lösung (Chrome 32, Firefox 27, IE 11, Safari 6) bekommen, die mit einer Kombination aus this und einer extrem einfachen Safari-Erweiterung arbeitet. Ein Großteil dieser Lösung wurde auf die eine oder andere Weise in dieser und dieser anderen Frage erwähnt.

Hier ist das Skript:

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

Die Safari-Erweiterung war einfach zu implementieren. Es bestand aus einer einzigen Zeile des Injektionsskripts:

myinject.js:

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

Dann müssen Sie in der Webseite JavaScript zuerst das Nachrichtenereignis registrieren und ein Kennzeichen setzen, wenn die Nachricht empfangen wird:

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

Dies setzt voraus, dass die Anwendung, die dem benutzerdefinierten Protokoll zugeordnet ist, die Installation der Safari-Erweiterung verwaltet.

Wenn der Rückruf false zurückgibt, müssen Sie in allen Fällen den Benutzer informieren, dass die Anwendung (d. H. Das benutzerdefinierte Protokoll) nicht installiert ist.

4
whiskeyspider

Sie können so etwas versuchen:

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
        }
    }
}
4
Ariel Guitian

Sie sagen, Sie müssen die Protokoll-Handler des Browsers erkennen - tun Sie das wirklich?

Was passiert, wenn Sie so etwas wie das passiert, wenn Sie eine Datei von Sourceforge herunterladen? Angenommen, Sie möchten myapp: // etwas öffnen. Erstellen Sie nicht nur einen Link, sondern einen Link zu einer anderen HTML-Seite, auf die über HTTP zugegriffen wird. Sagen Sie dann auf dieser Seite, dass Sie versuchen, die Anwendung für sie zu öffnen. Wenn dies nicht funktioniert, müssen Sie Ihre Anwendung installieren. Klicken Sie dazu auf den Link, den Sie bereitstellen. Wenn es funktioniert, sind Sie fertig.

3
Brian

Dies war ein empfohlener Ansatz für IE vom Microsoft-Support

http://msdn.Microsoft.com/de-de/library/ms537503%28VS.85%29.aspx#related_topics

"Wenn Sie die Kontrolle über die auf dem Computer eines Benutzers installierten Binärdateien haben, erscheint das Überprüfen des UA im Skript wie ein relevanter Ansatz: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Interneteinstellungen\5.0\User Agent\Post Platform " - Von M $ Support

Jede Webseite hat Zugriff auf den userAgent-String. Wenn Sie einen benutzerdefinierten Post-Plattform-Wert löschen, kann dies in Javascript mithilfe von navigator.userAgent erkannt werden.

Glücklicherweise werfen andere große Browser wie Firefox und Chrome (mit Ausnahme von Safari :() keine "Seite nicht gefunden" -Fehler auf, wenn auf einen Link mit einem benutzerdefinierten Protokoll geklickt wird und das Protokoll nicht auf dem Computer des Benutzers installiert ist. IE Hier ist sehr nachsichtig, jeder Trick zum Klicken in einen unsichtbaren Rahmen oder zum Auffinden von Javascript-Fehlern funktioniert nicht und führt zu einem hässlichen Fehler "Webseite kann nicht angezeigt werden". Der Trick, den wir in unserem Fall verwenden, besteht darin, Benutzer mit browserspezifischen Bildern darauf hinzuweisen, dass sie klicken Über den benutzerdefinierten Protokoll-Link wird eine Anwendung geöffnet. Wenn die Anwendung nicht gefunden wird, können sie auf eine "Installationsseite" klicken. In Bezug auf XD ist dies viel besser als der ActiveX-Ansatz für IE. .__ FF und Chrome, starten Sie einfach das benutzerdefinierte Protokoll ohne Erkennung. Lassen Sie den Benutzer Ihnen sagen, was er sieht .. Für Safari :( noch keine Antworten

1
Megha

Ich versuche, etwas Ähnliches zu tun und habe gerade einen Trick entdeckt, der mit Firefox funktioniert. Wenn Sie es mit dem Trick für IE kombinieren, können Sie einen haben, der auf beiden Hauptbrowsern funktioniert.

if (navigator.appName=="Microsoft Internet Explorer" && document.getElementById("testprotocollink").protocolLong=="Unknown Protocol") {
    alert("No handler registered");
} else {
    try {
        window.location = "custom://stuff";
    } catch(err) {
        if (err.toString().search("NS_ERROR_UNKNOWN_PROTOCOL") != -1) {
            alert("No handler registered");
        }
    }
}

Damit dies funktioniert, müssen Sie auch irgendwo auf der Seite einen ausgeblendeten Link haben:

<a id="testprotocollink" href="custom://testprotocol" style="display: none;">testprotocollink</a>

Es ist ein bisschen hackig, aber es funktioniert. Die Firefox-Version zeigt leider immer noch die Standardwarnung an, die angezeigt wird, wenn Sie versuchen, einen Link mit einem unbekannten Protokoll aufzurufen. Der Code wird jedoch ausgeführt, nachdem die Warnung abgewiesen wurde.

1
user200565

Dies ist keine triviale Aufgabe. Eine Option könnte die Verwendung von signiertem Code sein, den Sie für den Zugriff auf die Registrierung und/oder das Dateisystem nutzen können (beachten Sie, dass dies eine sehr teure Option ist). Es gibt auch keine einheitliche API oder Spezifikation für die Codesignierung, sodass Sie für jeden Zielbrowser einen spezifischen Code generieren müssen. Ein Alptraum der Unterstützung.

Ich weiß auch, dass Steam , das System zur Bereitstellung von Spielinhalten, dieses Problem offenbar auch nicht gelöst hat.

0
ken

Hier ist eine weitere hacklige Antwort, die (hoffentlich leichte) Änderungen an Ihrer Anwendung erforderlich macht, um beim Start "nach Hause zu telefonieren".

  1. Der Benutzer klickt auf den Link, wodurch versucht wird, die Anwendung zu starten. In den Link wird ein eindeutiger -Bezeichner eingefügt, der beim Starten an die __.-Anwendung übergeben wird. Eine Web-App zeigt einen Spinner oder etwas ähnliches.
  2. Die Webseite sucht dann von einer App mit derselben eindeutigen ID nach einem 'Application phone home' -Ereignis.
  3. Nach dem Start sendet Ihre Anwendung einen HTTP-Post an Ihre Webanwendung Mit der eindeutigen Kennung, um die Anwesenheit anzuzeigen. 
  4. Entweder wird auf der Webseite festgestellt, dass die Anwendung gestartet wurde, oder es wird eine Seite "Bitte herunterladen" angezeigt.
0
sethcall