62 votes

Comment vérifier si un protocole personnalisé est pris en charge

Nous utilisons un logiciel qui enregistre son propre protocole. Nous pouvons exécuter l'application à partir du navigateur puis par un lien comme :

customprotocol://do_this.

Mais existe-t-il un moyen de vérifier si un tel protocole personnalisé est supporté par le système de l'utilisateur ? Si ce n'est pas le cas, nous aimerions demander à l'utilisateur d'installer d'abord le logiciel.

Par exemple

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

Éditer Je connais la propriété protocolLong mais elle ne fonctionne que dans IE.

4 votes

Vous pouvez consulter le document suivant stackoverflow.com/questions/836777/

1 votes

Merci, j'ai déjà essayé la plupart des méthodes décrites ici. Il semble qu'il n'y ait pas de bonne façon de réaliser cela dans tous les navigateurs populaires sans alertes ou autres problèmes.

49voto

Andy E Points 132925

Malheureusement, il n'y a pas de moyen facile d'y parvenir. Il n'y a certainement pas de méthode pour déterminer à l'avance si le gestionnaire de protocole est installé ou non.

Internet Explorer Comme vous l'avez mentionné, le protocolLong mais j'ai du mal à faire en sorte qu'il renvoie autre chose que "Protocole inconnu" pour tous les gestionnaires de protocole personnalisés - si quelqu'un sait comment faire pour qu'IE renvoie la bonne valeur, merci de me le faire savoir afin que je puisse mettre à jour cette section. La meilleure solution que j'ai trouvée avec IE est de ajouter à la chaîne de l'agent utilisateur ou installez une extension de navigateur avec votre application qui expose une propriété accessible en Javascript.

Firefox est de loin le plus simple des principaux navigateurs, car il vous permet d'essayer de rattraper une tentative de navigation qui échoue. L'objet d'erreur renvoyé contient un name dont la valeur est NS_ERROR_UNKNOWN_PROTOCOL :

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

Firefox affichera sa propre boîte d'alerte :

Firefox ne sait pas comment ouvrir cette adresse, car le protocole (randomprotocolstring) n'est associé à aucun programme.

Une fois que vous avez fermé cette boîte, le catch s'exécutera et vous disposerez d'une solution de repli efficace.

Le deuxième est Opéra qui vous permet d'utiliser les lois de la prévisibilité pour détecter le succès d'un protocole personnalisé de lien cliqué. Si un clic de protocole personnalisé fonctionne, la page restera au même endroit. Si aucun gestionnaire n'est installé, Opera naviguera vers une page d'erreur. Il est donc assez facile de le détecter à l'aide d'une iframe :

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

Les setTimeout Il s'agit de s'assurer que nous vérifions l'emplacement après la navigation. Il est important de noter que si vous essayez d'accéder à la page, Opera lance une ReferenceException (erreur de sécurité inter-domaine). Cela n'a pas d'importance, car tout ce que nous avons besoin de savoir, c'est que l'emplacement est passé de about:blank , donc a try...catch fonctionne parfaitement.

Chrome est officiellement nulle à cet égard. Si un gestionnaire de protocole personnalisé échoue, il ne fait absolument rien. Si le gestionnaire fonctionne... vous l'avez deviné... il ne fait absolument rien. Il n'y a aucun moyen de faire la différence entre les deux, je le crains.

Je n'ai pas testé Safari mais je crains que ce soit la même chose que Chrome.

Nous vous invitons à essayer le code de test que j'ai écrit Je n'ai pas eu l'occasion de faire des recherches à ce sujet (j'avais moi-même un intérêt direct dans cette affaire). Il est compatible avec Opera et Firefox, mais ne fonctionne pas avec IE et Chrome.

3 votes

Comme cette réponse a été écrite en 2010, je dois mentionner pour les Googlers que dans une version plus récente de Firefox, la méthode try/catch ne semble plus avoir d'effet. (L'iframe permet toujours d'éviter une page d'erreur)

0 votes

Chrome et Safare perdent le focus (window.onblur peut être utilisé) si le handler est ouvert.

0 votes

@d512 dommage que le lien soit cassé maintenant.

12voto

Gearoid Murphy Points 4181

Nous avons utilisé FireBreath pour créer un simple plugin multiplateforme. Une fois installé, ce plugin enregistre un type de mime qui peut être détecté par le javascript du navigateur après un rafraîchissement de la page. La détection du type mime indique que le gestionnaire de protocole est installé.

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

1 votes

+Même s'il ne s'agit pas d'une méthode de détection "masquée" (IE demandera à l'utilisateur d'autoriser l'exécution d'ActiveXObjects), il s'agit d'une approche intelligente. En particulier pour Chrome, qui n'a pas d'autre solution, les plugins de navigateur peuvent être la seule option pour certaines personnes.

0 votes

FireBreath est un très bon moyen d'y remédier et il est très simple si c'est tout ce dont vous avez besoin. Je l'ai utilisé pour cela (après avoir essayé de trouver une solution au même problème).

1 votes

Pour que les gens sachent, Mozilla et Google considèrent les plugins comme une technologie héritée, Chrome a commencé à supprimer progressivement NPAPI, developer.chrome.com/extensions/npapi

9voto

antmeehan Points 63

Internet Explorer 10 sur Windows 8 a introduit le très utile navigator.msLaunchUri méthode de lancement d'un protocole URL personnalisé et de détection du succès ou de l'échec. Par exemple :

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

            return;
        }

Windows 7 / IE 9 et suivants supportent les commentaires conditionnels comme suggéré par @mark-kahn.

1 votes

Veuillez noter que le msLaunchUri n'existe que dans IE >= 10 sur Windows 8 .

0 votes

@aaronk6. Je ne suis pas sûr que ce soit correct, car j'ai utilisé cette méthode sous Windows 7.

2 votes

J'ai vérifié IE 10 et IE 11 sur Windows 7. Dans les deux cas, typeof navigator.msLaunchUri retours "undefined" . Microsoft a également confirmé que cette API n'a pas été ajoutée à Windows 7 : La fonction API documentée "navigator.msLaunchUri" n'est pas présente dans Windows 7 (voir le commentaire du 5/5/2014 à 12:27)

4voto

Mark Kahn Points 79

Pour Internet Explorer, la meilleure solution que j'ai trouvée est d'utiliser Conditionl comments & Version Vector (l'application doit écrire quelque chose dans le registre lors de l'installation du protocole, voir http://msdn.microsoft.com/en-us/library/ms537512.aspx#Version_Vectors ). protocolLong ne fonctionne pas pour les protocoles personnalisés.

1 votes

Pour Chrome, il est peut-être possible d'enregistrer un temps MIME lors de l'installation, et de le vérifier en utilisant window.navigator.mimeTypes[i] . Je n'ai pas trouvé de moyen facile de le faire.

2 votes

+1, c'est une bonne solution de contournement pour IE 9 et les versions inférieures, Mark. Malheureusement, IE 10 ne supporte plus les commentaires conditionnels. protocolLong question.

3voto

David W. Keith Points 1111

Sur mobile, vous pouvez utiliser une iframe intégrée pour basculer automatiquement entre le protocole personnalisé et un protocole connu (web ou app store), voir https://gist.github.com/2662899

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X