2010-02-24 22 views
20

Tengo un protocolo (como http) con un esquema administrado con una aplicación de terceros registrada en Mac OS X. Es decir, x-someapp: // someaction o algo así.¿Es posible abrir un esquema de URL personalizado con Google Chrome?

¿Cómo puedo abrir esta URL con Google Chrome? De forma predeterminada, Chrome comienza a buscar en el motor de Google, en su lugar, inicia la aplicación y le pasa el control de URL ...

Safari inicia algunas aplicaciones registradas. Y es lo correcto.

Firefox y Opera le preguntan qué hacer ... y también puedo iniciar la aplicación.

Pero Chrome ... No pregunta.

Incluso he intentado escribir alguna página HTML con JavaScript dentro de enviar XHttpRequest:

function _httpExecuteCallback() 
{ 
if (httpRequestCallbackFunction != null) { 
    if (httpRequest.readyState == 4) { 
    if (httpRequest.status == 200) { 
    httpRequestCallbackFunction(); 
    httpRequestCallbackFunction = null; 
    } 
    } 
} 
} 

function _httpGet(url, callbackFunction) 
{ 
httpRequest = false; 
httpRequestCallbackFunction = callbackFunction; 
httpRequest = new XMLHttpRequest(); 
httpRequest.onreadystatechange = _httpExecuteCallback; 
httpRequest.open('GET', url, true); 
httpRequest.send(null); 
} 


_httpGet('x-someapp://test',function(){}) 

No hay resultados también ...

Respuesta

2

Encontré la solución que funciona con Chrome. Uso el IFRAME-way.

Ejemplo (con jQuery):

$("body").append('<span id="__protoProxy"></span>'); 

function queryWord(aWord) 
{ 
var protoProxy = document.getElementById('__protoProxy'); 
if (protoProxy) 
{ 
    var word = aWord.replace('"','\"'); 
    protoProxy.innerHTML = '<div style="display:none;"><iframe src="x-myproto://query?' + word + '"></iframe></div>'; 
} 
} 

queryWord('hello'); 
+1

Ah, así que, en lugar de escribir 'x-myproto: // query? Furries' en la barra de direcciones, ¿abres un iframe con él, y luego Chrome usa la aplicación registrada existente para buscar lo que se va a mostrar dentro del iframe? –

+0

Esto es necesario para nuestro complemento de Chrome, nadie ingresa la dirección directamente en la barra de ubicación del usuario, por lo que el iframe oculto es la mejor solución. – UncleMiF

2

Si Chrome no reconoce el esquema de URL, el valor predeterminado es una búsqueda .

Esto es lo que veo en Safari: alt text http://img62.imageshack.us/img62/6792/clipboard02oh.jpg

y en Firefox:

alt text http://img138.imageshack.us/img138/9986/clipboard04xk.jpg

Creo que la razón por la cual los valores predeterminados de Chrome para buscar es que hay búsquedas de Google especiales que utilizan el colon.

Ej:

  • definen: diccionario
  • filetype: pdf google cromo

Ésta es una de las molestias que tengo con Firefox, tengo que saltar a la "caja de búsqueda" en lugar de la barra de direcciones para ejecutar estos tipos de búsquedas. Como Chrome no tiene un cuadro de búsqueda independiente como Firefox, IE y Safari, esta funcionalidad es obligatoria.

Las solicitudes de Ajax no le darán la vuelta.

+0

No sé cómo funciona en Windows, etiqueté esta pregunta como Mac OS X. Por lo tanto, en el Mac OS X World, cualquier aplicación puede registrar su propio esquema de Internet dentro del archivo Info.plist (que contiene Paquete de aplicaciones). Por lo tanto, Safari siempre sabrá sobre los protocolos de terceros, ya que solo se instaló una nueva aplicación, incluso Firefox y Opera lo sabrán, pero parece que Chrome no lee esta información del sistema. Por ejemplo, si tengo instalado SpamSieve, puedo abrir el protocolo x-spamsieve directamente desde Safari y registrar el software ... Safari puede simplemente redirigir esta consulta de esquema URL al NSWorkspace ... – UncleMiF

+0

Además, tuve éxito utilicé AJAX de Firefox (vea el ejemplo del código dentro de mi pregunta) en Mac OS X para solicitar protocolos de terceros (no http/ftp). Aquí es – UncleMiF

+1

ejemplos adicionales http://mac.gettranslateit.com/integrationFireFox.shtml y http://mac.gettranslateit.com/integrationOpera.shtml Sólo quiero escribir extensión de Chrome, y generalmente lo hacía, excepto caja de arena Restricciones: ahora necesito llamar al protocolo de un tercero (el mío), pero no puedo. – UncleMiF

7

Parece que es el análisis sintáctico Locationbar de Google que está recibiendo en el camino.

El navegador, sin embargo, parece manejar correctamente los esquemas de URL personalizados. Pruebe esto en su barra de direcciones:

javascript:document.location = 'myscheme://whatever' 

Cualquier enlace en su página que use el esquema personalizado también debería hacer lo correcto.

23

La solución aceptada actualmente tiene un problema con Chrome para SSL https.Viendo el registro de la consola, Chrome bloquea la solicitud, ya que piensa el protocolo URL personalizada no es segura:

[blocked] The page at reports blah blah ran insecure content from customproto//blah blah 

Aquí es una solución (esto me tomó unos días para investigar):

<input type='button' value='Test Custom Url' onclick='exec()'> 

    <script> 
    function submitRequest(buttonId) { 
     var d = (window.parent)?window.parent.document:window.document 
     if (d.getElementById(buttonId) == null || d.getElementById(buttonId) == undefined) return; 
     if (d.getElementById(buttonId).dispatchEvent) { 
       var e = d.createEvent("MouseEvents"); 
       e.initEvent("click", true, true); 
       d.getElementById(buttonId).dispatchEvent(e); 
     } 
     else { 
       d.getElementById(buttonId).click(); 
     } 
    } 

    function exec(){ 
     var d = (window.parent)?window.parent.document:window.document 
     var f = d.getElementById('customUrlLink') 
     if (f) {f.parentNode.removeChild(f);} 
     var a = d.createElement('a'); 
     a.href = 'mycustomproto://arg1';  
     a.innerHTML = "Link"          
     a.setAttribute('id',  'customUrlLink'); 
     a.setAttribute("style", "display:none; "); 
     d.body.appendChild(a); 
     submitRequest("customUrlLink"); 
    } 
    </script> 

Este el código no funcionará para IE. He encontrado que al utilizar esta técnica, IE limita el argumento del protocolo personalizado a menos de 1000, ya que al usar la técnica de iFrame, IE permitirá 2083 caracteres.

La única manera de superar el límite de URL en JavaScript es chuck los datos y llamar varias veces. Si alguien quiere echar un vistazo a eso, por favor, hágame saber cómo va. Me gustaría usarlo

Para manejar las direcciones URL largas en la aplicación de la ejecución, pasar una ficha en la aplicación y hacer que ir a buscar los datos de una URL GET.

Así que por ahora estoy usando una función para Chrome/FF y otra función para IE.

Estos enlaces me ayudaron a desarrollar esta solución:

https://superuser.com/questions/655405/custom-protocol-handler-not-working-in-chrome-on-ssl-page

Simulating a click in jQuery/JavaScript on a link

(Ojalá hubiera sabido esto hace unos días .... espero que esto ayude a alguien)

= =================================================

actualización: (8 horas más tarde)

=============================================== ===

Jake registró una gran solución para el cromo: https://superuser.com/questions/655405/custom-protocol-handler-not-working-in-chrome-on-ssl-page

esto funciona solamente en cromo:

window.location.assign("customprotocol://"); 

se producirá un error en un iframe por lo que este está funcionando:

var w = (window.parent)?window.parent:window 
w.location.assign(service + '://' + data) 

================================== =============

Actualización: (semanas más tarde)

======================= ==============================

Todos los ejemplos de apertura del protocolo personalizado, incluido el mío, tienen un ":// "en la url. Y esto es lo que está causando las advertencias SSL.

Resulta que la solución es cambiar ": //" a ":"

dé su explicación:

src="x-myproto:query" ..... 

y las advertencias SSL desaparecerá.

============================================== ====

Seguimiento: (después de meses de uso en producción)

============================= =====================

Esto ha funcionado bien para chorme. Detecta el navegador y si Chrome hace esto:

var w = (window.parent)?window.parent:window 
w.location.assign('myproto://xyzabcdefetc') 

Para IE y otros navegadores hago algo ligeramente diferente.

Tenga en cuenta que los navegadores imponen un límite a la cantidad de datos que puede poner en el protocolo url personalizado. Siempre que su cadena tenga menos de 800 caracteres, este parece ser el número mágico que funciona en todos los navegadores.

+1

Brian, gracias por la publicación, pero no veo cómo esto resuelve el problema en Chrome. Nuestra aplicación utiliza un iframe para otros navegadores para evitar la navegación fuera de la aplicación y al mismo tiempo lanzar el controlador de URL (SSH en nuestro caso). Esto solía funcionar en Chrome pero ahora está roto. Cuando empleo su solución (sin un iframe) se produce una navegación fuera de nuestra aplicación cuando se lanza el controlador de URL. Así que no estoy seguro de cómo la respuesta anterior es una "solución" al problema. ¿Me estoy perdiendo de algo? – brettw

+0

@brettw, he agregado una actualización a la respuesta. Realmente está diciendo más o menos lo mismo. Lo que he publicado es trabajar en Chrome para mí. Esto ha estado en producción por algún tiempo ahora.Si esta solución está navegando, intente usar un href para llamar a una función js como test y luego ponga el código en la solución en la función de prueba(). –

+0

@BrianMcGinity - en Chrome haciendo window.location.assign está cambiando el contenido de la pestaña para volver a la página anterior (que es la página de autorización/inicio de sesión que ya no es válida). ¿Hay alguna forma de hacerlo permanecer en esa página? – Noitidart

3

Aquí hay una solución que también incluye un redireccionamiento a la App Store/Play Store si el usuario no tiene la aplicación. Utiliza un setTimeout para esto. También hace uso de un iframe para admitir más navegadores. Así que esto funciona en Chrome y en cualquier otro navegador móvil. Usamos esto como mi compañía, Branch. Simplemente modifique los dos enlaces a continuación para que se correspondan con su URI y el enlace de App Store.

<!DOCTYPE html> 
<html> 
    <body> 
     <script type="text/javascript"> 
      window.onload = function() { 
       // Deep link to your app goes here 
       document.getElementById("l").src = "my_app://somepath"; 

       setTimeout(function() { 
        // Link to the App Store should go here -- only fires if deep link fails     
        window.location = "https://itunes.apple.com/us/app/myapp/id123456789?ls=1&mt=8"; 
       }, 500); 
      }; 
     </script> 
     <iframe id="l" width="1" height="1" style="visibility:hidden"></iframe> 
    </body> 
</html> 

De nuevo, esto debería funcionar en cualquier navegador, gracias al iframe.

Cuestiones relacionadas