He creado un controlador de protocolo de URL personalizado.
http://
mailto://
custom://
He registrado una aplicación WinForms para responder en consecuencia. Todo esto funciona muy bien.
Pero me gustaría poder manejar con gracia el caso en el que el usuario aún no tiene instalado el controlador de protocolo de URL personalizado.
Para poder hacer esto, necesito poder detectar los controladores de protocolo registrados del navegador, supongo que de JavaScript. Pero no he podido encontrar una manera de sondear la información. Espero encontrar una solución a este problema.
Gracias por cualquier idea que pueda compartir.
javascript
browser
protocols
moniker
Chris Craft
fuente
fuente
Respuestas:
Esta sería una forma muy , muy peligrosa de hacer esto ... pero ¿funcionaría?
Lejos de ser a prueba de balas ... ¿pero podría ayudar?
fuente
No existe una forma excelente de hacerlo en varios navegadores. En IE10 + en Win8 +, una nueva
msLaunchUri
api le permite lanzar un protocolo, así:navigator.msLaunchUri('skype:123456', function() { alert('success'); }, function() { alert('failed'); } );
Si el protocolo no está instalado, se activará la devolución de llamada de falla. De lo contrario, el protocolo se iniciará y se activará la devolución de llamada exitosa.
Discuto este tema un poco más aquí: http://blogs.msdn.com/b/ieinternals/archive/2011/07/14/url-protocols-application-protocols-and-asynchronous-pluggable-protocols-oh-my .aspx
fuente
HTML5 define esquemas personalizados y manejadores de contenido (que yo sepa, Firefox es el único implementador hasta ahora), pero desafortunadamente actualmente no hay forma de verificar si ya existe un manejador; se ha propuesto , pero no hubo seguimiento. Esto parece una característica fundamental para usar los controladores personalizados de manera efectiva y nosotros, como desarrolladores, debemos prestar atención a este problema para implementarlo.
fuente
Parece que no hay una forma sencilla a través de JavaScript para detectar la presencia de una aplicación instalada que haya registrado un controlador de protocolo.
En el modelo de iTunes, Apple proporciona direcciones URL a sus servidores, que luego proporcionan páginas que ejecutan algunos javascript:
http://ax.itunes.apple.com/detection/itmsCheck.js
Entonces, el instalador de iTunes aparentemente implementa complementos para los principales navegadores, cuya presencia puede detectarse.
Si su complemento está instalado, puede estar razonablemente seguro de que la redirección a la URL específica de su aplicación se realizará correctamente.
fuente
Lo que parece la solución más fácil es preguntarle al usuario la primera vez.
Usando un cuadro de diálogo de confirmación de Javascript por ejemplo:
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/'
fuente
Si tiene el control del programa que está tratando de ejecutar (el código), una forma de ver si el usuario tuvo éxito al ejecutar la aplicación sería:
Antes de intentar abrir el protocolo personalizado, realice una solicitud AJAX a un script del servidor que guarde la intención del usuario en una base de datos (por ejemplo, guarde el ID de usuario y lo que quería hacer).
Intente abrir el programa y transmita los datos de la intención.
Haga que el programa haga una solicitud al servidor para eliminar la entrada de la base de datos (utilizando los datos de la intención para encontrar la fila correcta).
Haga que javascript sondee el servidor por un tiempo para ver si la entrada de la base de datos se ha ido. Si la entrada desaparece, sabrá que el usuario logró abrir la aplicación; de lo contrario, la entrada permanecerá (puede eliminarla más tarde con cronjob).
No he probado este método, solo lo pensé.
fuente
Finalmente pude obtener una solución de navegador cruzado (Chrome 32, Firefox 27, IE 11, Safari 6) que funciona con una combinación de esto y una extensión de Safari súper simple. Gran parte de esta solución se ha mencionado de una forma u otra en esta y otra pregunta .
Aquí está el guión:
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); } }
La extensión de Safari fue fácil de implementar. Consistía en una sola línea de script de inyección:
myinject.js:
window.postMessage("myappinstalled", window.location.origin);
Luego, en la página web JavaScript, primero debe registrar el evento del mensaje y establecer una bandera si se recibe el mensaje:
window.addEventListener('message', function (msg) { if (msg.data === "myappinstalled") { myappinstalledflag = true; } }, false);
Esto supone que la aplicación que está asociada con el protocolo personalizado administrará la instalación de la extensión de Safari.
En todos los casos, si la devolución de llamada devuelve falso, sabrá informar al usuario que la aplicación (es decir, su protocolo personalizado) no está instalada.
fuente
myWindow.location.href;
iframesrc
definido dentro de esa ventana? ¿Se supone que debe lanzar una excepción? No lo hace independientemente de si el protocolo personalizado es compatible o no.Dice que necesita detectar los controladores de protocolo del navegador, ¿de verdad?
¿Qué pasa si hiciste algo como lo que sucede cuando descargas un archivo de sourceforge? Digamos que quieres abrir myapp: // algo. En lugar de simplemente crear un enlace, cree un enlace a otra página HTML a la que se acceda a través de HTTP. Luego, en esa página, diga que está intentando abrir la aplicación para ellos. Si no funciona, deben instalar su aplicación, lo que pueden hacer haciendo clic en el enlace que proporcionará. Si funciona, entonces está todo listo.
fuente
Puedes probar algo como esto:
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 } } }
fuente
Estoy tratando de hacer algo similar y acabo de descubrir un truco que funciona con Firefox. Si lo combina con el truco para IE, puede tener uno que funcione en ambos navegadores principales (no estoy seguro de si funciona en Safari y sé que no funciona en Chrome)
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"); } } }
Para que esto funcione, también debe tener un enlace oculto en algún lugar de la página, como este:
<a id="testprotocollink" href="custom://testprotocol" style="display: none;">testprotocollink</a>
Es un poco hacky pero funciona. Desafortunadamente, la versión de Firefox todavía muestra la alerta predeterminada que aparece cuando intenta visitar un enlace con un protocolo desconocido, pero ejecutará su código después de que se descarte la alerta.
fuente
Este fue un enfoque recomendado para IE por el soporte de Microsoft
http://msdn.microsoft.com/en-us/library/ms537503%28VS.85%29.aspx#related_topics
"Si tiene cierto control sobre los archivos binarios que se instalan en la máquina de un usuario, verificar el UA en el script parece un enfoque relevante: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Internet Settings \ 5.0 \ User Agent \ Post Platform" - Por soporte de M $
Cada página web tiene acceso a la cadena userAgent y si suelta un valor de plataforma de publicación personalizada, detectar esto en javascript usando navigator.userAgent es bastante simple.
Afortunadamente, otros navegadores importantes como Firefox y Chrome (salvo Safari :(), no arrojan errores de "página no encontrada" cuando se hace clic en un enlace con un protocolo personalizado y el protocolo no está instalado en la máquina del usuario. IE es muy implacable aquí , cualquier truco para hacer clic en un marco invisible o capturar errores de javascript no funciona y termina con un feo error "no se puede mostrar la página web". El truco que usamos en nuestro caso es informar a los usuarios con imágenes específicas del navegador que hacen clic en el protocolo personalizado El enlace abrirá una aplicación. Y si no encuentran la aplicación que se abre, pueden hacer clic en una página de "instalación". En términos de XD, esto funciona mucho mejor que el enfoque ActiveX para IE. Para FF y Chrome, simplemente adelante e inicie el protocolo personalizado sin ninguna detección. Deje que el usuario le diga lo que ve. Para Safari,:(aún no hay respuestas
fuente
Ésta no es una tarea trivial; una opción podría ser utilizar código firmado, que podría aprovechar para acceder al registro y / o al sistema de archivos (tenga en cuenta que esta es una opción muy cara ). Tampoco existe una API o especificación unificada para la firma de código, por lo que se le pedirá que genere un código específico para cada navegador de destino. Una pesadilla de apoyo.
Además, sé que Steam , el sistema de entrega de contenido de juegos, tampoco parece tener este problema resuelto.
fuente
Aquí hay otra respuesta hacky que requeriría (con suerte, una ligera) modificación de su aplicación para 'llamar a casa' en el lanzamiento.
fuente