2010-05-20 19 views
48

Utilizziamo software che registra il proprio protocollo. Siamo in grado di eseguire l'applicazione dal browser poi da link come:Come verificare se è supportato un protocollo personalizzato

customprotocol://do_this. 

, ma c'è un modo per controllare è tale protocollo personalizzato supportato dal sistema gli utenti? Altrimenti, vorremmo chiedere all'utente di installare prima il software.

es:

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

Edit so sulla proprietà protocolLong ma funziona solo in IE.

+4

Si potrebbe desiderare di avere una lettura di http://stackoverflow.com/questions/836777/how-to-detect-browsers-protocol-handlers –

+1

Thx, già provato la maggior parte dei metodi descritti lì. Sembra che non ci sia un buon modo per ottenere questo risultato in tutti i browser più popolari senza avvisi o altri problemi. –

risposta

44

Sfortunatamente, non esiste un modo semplice per raggiungere questo obiettivo. Non c'è certamente alcun metodo per predeterminare se il gestore del protocollo è installato o meno.

Internet Explorer, come lei ha ricordato, ha la proprietà protocolLong ma sto avendo difficoltà a farla tornare qualcosa di diverso da "Sconosciuto Protocol" per tutti i gestori di protocollo su misura - se qualcuno sa come ottenere IE per tornare il valore corretto per favore fatemelo sapere così posso aggiornare questa sezione. La soluzione migliore che ho trovato con IE è append to the user agent string o installa un'estensione del browser insieme alla tua app che espone una proprietà accessibile Javascript.

Firefox è di gran lunga il più semplice tra i principali browser, in quanto consente di provare e rilevare un tentativo di navigazione che non riesce. L'oggetto di errore restituito contiene una proprietà name il cui valore è NS_ERROR_UNKNOWN_PROTOCOL:

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

Firefox si aprirà con una propria finestra di avviso:

Firefox non sa come aprire questo indirizzo, perché il protocollo (randomprotocolstring) non è associato ad alcun programma.

Una volta chiusa questa casella, verrà eseguito il blocco catch e sarà disponibile un fallback funzionante.

Secondo è Opera, che consente di utilizzare le leggi di prevedibilità per rilevare il successo di un collegamento protocollo personalizzato cliccato. Se un clic del protocollo personalizzato funziona, la pagina rimarrà nella stessa posizione. Se non è installato alcun gestore, Opera passerà a una pagina di errore. Questo rende piuttosto facile da individuare con un iframe:

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

Il setTimeout qui è quello di assicurarsi controlliamo la posizione dopo navigazione. È importante notare che se si tenta di accedere alla pagina, Opera genera una ReferenceException (errore di sicurezza tra domini). Non importa, perché tutto quello che dobbiamo sapere è che la posizione è cambiata da about:blank, quindi un try...catch funziona bene.

Chrome fa schifo ufficialmente con questo proposito. Se un gestore di protocollo personalizzato fallisce, lo fa assolutamente zip. Se il conduttore funziona ... hai indovinato ... lo fa assolutamente zip. Non ho modo di differenziare i due, temo.

Non ho provato Safari ma temo che sarebbe lo stesso di Chrome.

Si consiglia di provare lo test code I wrote mentre si esamina questo (ho avuto un interesse personale in esso stesso). Opera compatibile con Firefox e Firefox, ma attualmente non fa nulla in IE e Chrome.

+1

Si potrebbe voler controllare questo. http://www.rajeshsegu.com/2012/09/browser-detect-custom-protocols/comment-page-1/ È uno script che dovrebbe funzionare su tutti i browser (ma non funziona su IE). Ha una soluzione alternativa, ma funzionante, per Chrome. – d512

+2

Dal momento che questa risposta è stata scritta nel 2010, dovrei menzionare per i googler che in una versione più recente di Firefox il metodo try/catch sembra non avere più alcun effetto. (L'iframe evita comunque una pagina di errore) – Katana314

+0

Chrome e Safare perdono il focus (window.onblur può essere utilizzato) se il gestore è aperto. –

4

Per Internet Explorer, la soluzione migliore che ho trovato è utilizzare i commenti Conditionl & Versione Vector (l'applicazione deve scrivere qualcosa sul registro durante l'installazione del protocollo, vedere http://msdn.microsoft.com/en-us/library/ms537512.aspx#Version_Vectors). protocolLong non funziona per il protocollo personalizzato.

+1

Per Chrome, forse è possibile registrare un tempo MIME durante l'installazione e controllarlo usando 'window.navigator.mimeTypes [i]'. Non ho trovato un modo semplice per farlo. –

+1

+1, questa è una buona soluzione per IE 9 e inferiore, Mark. Sfortunatamente, IE 10 non supporta più i commenti condizionali, ma forse hanno risolto il problema "protocolLong'. –

3

Sul cellulare è possibile utilizzare un iframe incorporato per sensore tra il protocollo personalizzato e una nota (web o App Store), vedi https://gist.github.com/2662899

11

Solo per carillon con la nostra esperienza, abbiamo utilizzato dello sputare fuoco per creare un semplice plugin multipiattaforma. Una volta installato, questo plugin registra un tipo mime che può essere rilevato dal browser javascript dopo l'aggiornamento della pagina. Il rilevamento del tipo mime indica che il gestore del protocollo è installato.

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

+ 1 - pur non essendo un metodo di rilevamento "occultato" (IE chiederà all'utente di consentire l'esecuzione di ActiveXObjects), si tratta comunque di un approccio intelligente. In particolare per Chrome, che non ha altre soluzioni, i plugin del browser potrebbero essere l'unica opzione per alcune persone. –

+0

FireBreath è un ottimo modo per risolvere questo problema ed è davvero semplice se è tutto ciò che serve. L'ho usato per questo (dopo aver provato a trovare una soluzione allo stesso problema). –

+1

Solo così le persone sanno, Mozilla e Google considerano i plug-in una tecnologia legacy, Chrome ha iniziato a eliminare NPAPI, https://developer.chrome.com/extensions/npapi – Burjua

7

Internet Explorer 10 su Windows 8 ha introdotto il metodo molto utile navigator.msLaunchUri per il lancio di un URL protocollo personalizzato e rilevare il successo o il fallimento. Per esempio:

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

      return; 
     } 

Windows 7/IE 9 e sotto il supporto commenti condizionali come suggerito da @ mark-Kahn.

+1

Si noti che il metodo 'msLaunchUri' esiste solo in IE> = 10 ** su Windows 8 **. – aaronk6

+0

@ aaronk6. Non sono sicuro che sia corretto, poiché stavo usando questo metodo su Windows 7. – antmeehan

+1

Ho controllato IE 10 e IE 11 su Windows 7. In entrambi i casi, 'typeof navigator.msLaunchUri' restituisce' "undefined" '. Inoltre, Microsoft ha confermato che questa API non è stata aggiunta a Windows 7: [Funzione API documentata 'navigator.msLaunchUri' non presente in Windows 7] (https://connect.microsoft.com/IE/feedback/details/864863/documented-api-function-navigator-mslaunchuri-not-present-in-windows-7) (vedi commento dal 5/5/2014 alle 12:27) – aaronk6

1

Ecco una risposta off-the-wall: installa un carattere insolito al momento della registrazione del protocollo personalizzato. Quindi usa javascript per verificare se quel font esiste, usando qualcosa like this.

Sicuramente è un trucco, ma a differenza delle altre risposte funzionerebbe su browser e sistemi operativi.

+0

Risposta molto bella! +1 –

+0

Non ho capito –

1

Voglio solo spiegare più la precedente risposta di Mark (alcune persone non hanno capito per esempio user7892745).

1) Quando si avvia la pagina Web o l'applicazione Web, si verifica un carattere insolito (qualcosa come il carattere Konfuciuz cinese http://www.fontspace.com/apostrophic-lab/konfuciuz).

Di seguito si riporta il codice di campione pagina web con la funzione che controlla il tipo di carattere (chiamato isFontAvailable):

<!DOCTYPE html> 
<html> 
<head> 

</head> 
<body> 

<script> 
/** 
* Checks if a font is available to be used on a web page. 
* 
* @param {String} fontName The name of the font to check 
* @return {Boolean} 
* @license MIT 
* @copyright Sam Clarke 2013 
* @author Sam Clarke <[email protected]> 
*/ 
(function (document) { 
    var width; 
    var body = document.body; 

        var container = document.createElement('span'); 
        container.innerHTML = Array(100).join('wi'); 
        container.style.cssText = [ 
     'position:absolute', 
     'width:auto', 
     'font-size:128px', 
     'left:-99999px' 
    ].join(' !important;'); 

    var getWidth = function (fontFamily) { 
     container.style.fontFamily = fontFamily; 

     body.appendChild(container); 
     width = container.clientWidth; 
     body.removeChild(container); 

     return width; 
    }; 

    // Pre compute the widths of monospace, serif & sans-serif 
    // to improve performance. 
    var monoWidth = getWidth('monospace'); 
    var serifWidth = getWidth('serif'); 
    var sansWidth = getWidth('sans-serif'); 

    window.isFontAvailable = function (font) { 
     return monoWidth !== getWidth(font + ',monospace') || 
      sansWidth !== getWidth(font + ',sans-serif') || 
      serifWidth !== getWidth(font + ',serif'); 
    }; 
})(document); 



function isProtocolAvailable() 
{ 
    if (isFontAvailable('Konfuciuz')) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

function checkProtocolAvail() 
{ 
    if (isProtocolAvailable()) 
    { 
     alert('Custom protocol is available!'); 
    } 
    else 
    { 
     alert('Please run executable to install protocol!'); 
    } 
} 
</script> 

<h3>Check if custom protocol was installed or not</h3> 

<pre> 


<input type="button" value="Check if custom protocol was installed!" onclick="checkProtocolAvail()"> 

</body> 
</html> 

2) La prima volta quando l'utente apre questa pagina, tipo di carattere non verrà installato in modo egli otterrà un messaggio che dice "Esegui eseguibile per installare il protocollo personalizzato ...".

3) Eseguirà eseguibile che installerà il carattere. Il vostro exe può semplicemente copiare il file di font (nel mio caso è KONFUC __ TTF.) Nella directory C: \ Windows o utilizzando un codice come questo (ad esempio su Delphi):

// Adding the font .. 

AddFontResource(PChar('XXXFont.TTF')); 
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0); 

4) Dopo di che, quando l'utente esegue nuovamente l'app Web, ottiene "Protocollo personalizzato disponibile!" messaggio perché il font è stato installato questa volta.

Testato su Google Chrome, Internet Explorer e Firefox: ottimo funzionamento!

Problemi correlati