Il modo migliore per utilizzare jQuery in hosting su Google, ma fallire nella libreria ospitata su Google

Quale sarebbe un buon modo per provare a caricare il jQuery ospitato su Google (o altre librerie ospitate da Google), ma caricare la mia copia di jQuery se il tentativo di Google fallisce?

Non sto dicendo che Google è traballante. Ci sono casi in cui la copia di Google è bloccata (apparentemente in Iran, per esempio).

Dovrei impostare un timer e controllare l’object jQuery?

Quale sarebbe il pericolo che entrambe le copie arrivassero?

Non sono davvero alla ricerca di risposte come “usa solo Google” o “usa la tua”. Capisco quegli argomenti. Comprendo inoltre che è probabile che l’utente abbia memorizzato nella cache la versione di Google. Sto pensando ai fallback per il cloud in generale.


Modifica: questa parte ha aggiunto …

Poiché Google suggerisce di utilizzare google.load per caricare le librerie di ajax e, al termine, esegue una richiamata, mi chiedo se sia la chiave per serializzare questo problema.

So che sembra un po ‘pazzo. Sto solo cercando di capire se può essere fatto in modo affidabile o meno.


Aggiornamento: jQuery ora ospitato sul CDN di Microsoft.

http://www.asp.net/ajax/cdn/

    Puoi ottenerlo in questo modo:

      

    Questo dovrebbe essere nel della tua pagina e qualsiasi gestore di eventi jQuery ready dovrebbe essere nel per evitare errori (anche se non è infallibile!).

    Un altro motivo per non utilizzare jQuery ospitato da Google è che in alcuni paesi il nome di dominio di Google è vietato.

    Il modo più semplice e pulito per fare questo di gran lunga:

       

    Questo sembra funzionare per me:

           

    hello jQuery

    Il modo in cui funziona è utilizzare l'object google che chiama http://www.google.com/jsapi carica sull'object window . Se quell'object non è presente, supponiamo che l'accesso a Google stia fallendo. Se questo è il caso, carichiamo una copia locale usando document.write . (Sto usando il mio server in questo caso, per favore usa il tuo per testarlo).

    window.google.load anche la presenza di window.google.load - Potrei anche fare un controllo di tipo per vedere che le cose sono oggetti o funzioni come appropriato. Ma penso che questo faccia il trucco.

    Ecco solo la logica di caricamento, poiché l'evidenziazione del codice sembra fallire da quando ho postato l'intera pagina HTML che stavo testando:

     if (window.google && window.google.load) { google.load("jquery", "1.3.2"); } else { document.write(' 

    Anche se devo dire, non sono sicuro che se si tratta di una preoccupazione per i visitatori del tuo sito, dovresti armeggiare con l' API di Google AJAX Libraries .

    Fatto divertente : inizialmente ho provato ad usare un blocco try..catch per questo in varie versioni ma non ho trovato una combinazione pulita come questa. Sarei interessato a vedere altre implementazioni di questa idea, puramente come esercizio.

    Se hai modernizr.js incorporato nel tuo sito, puoi utilizzare yepnope.js incorporato per caricare i tuoi script in modo asincrono – tra gli altri jQuery (con fallback).

     Modernizr.load([{ load : '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js' },{ test : window.jQuery, nope : 'path/to/local/jquery-1.7.2.min.js', both : ['myscript.js', 'another-script.js'], complete : function () { MyApp.init(); } }]); 

    Questo carica jQuery da Google-cdn. Successivamente viene controllato, se jQuery è stato caricato correttamente. In caso contrario (“nope”), viene caricata la versione locale. Anche i tuoi script personali sono caricati – il “entrambi” indica che il processo di caricamento è ingiunto indipendentemente dal risultato del test.

    Quando tutti i processi di caricamento sono completi, viene eseguita una funzione, nel caso “MyApp.init”.

    Personalmente preferisco questo modo di caricare gli script asincroni. E poiché faccio affidamento sui feature-test forniti da modernizr quando costruisco un sito, lo ho comunque incorporato nel sito. Quindi non c’è in realtà nessun sovraccarico.

     if (typeof jQuery == 'undefined') { // or if ( ! window.jQuery) // or if ( ! 'jQuery' in window) // or if ( ! window.hasOwnProperty('jQuery')) var script = document.createElement('script'); script.type = 'text/javascript'; script.src = '/libs/jquery.js'; var scriptHook = document.getElementsByTagName('script')[0]; scriptHook.parentNode.insertBefore(script, scriptHook); } 

    Dopo aver tentato di includere la copia di Google dal CDN.

    In HTML5, non è necessario impostare l’attributo type .

    Puoi anche usare …

     window.jQuery || document.write(' 

    Ci sono alcune grandi soluzioni qui, ma mi piacerebbe fare un ulteriore passo in avanti per quanto riguarda il file locale.

    In uno scenario in cui Google non funziona, dovrebbe caricare una sorgente locale, ma forse un file fisico sul server non è necessariamente l’opzione migliore. Ne parlo perché attualmente sto implementando la stessa soluzione, voglio solo tornare a un file locale generato da un’origine dati.

    La mia ragione è che voglio avere un po ‘di testa quando si tratta di tenere traccia di ciò che carico da Google rispetto a quello che ho sul server locale. Se voglio cambiare versioni, desidero mantenere la mia copia locale sincronizzata con quello che sto cercando di caricare da Google. In un ambiente in cui ci sono molti sviluppatori, penso che l’approccio migliore sarebbe quello di automatizzare questo processo in modo che tutto ciò che si dovrebbe fare sia modificare un numero di versione in un file di configurazione.

    Ecco la mia soluzione proposta che dovrebbe funzionare in teoria:

    • In un file di configurazione dell’applicazione, memorizzerò 3 elementi: l’URL assoluto per la libreria, l’URL per l’API JavaScript e il numero di versione
    • Scrivi una class che ottiene il contenuto del file della libreria stessa (ottiene l’URL dalla config dell’app), la memorizza nella mia origine dati con il nome e il numero di versione
    • Scrivi un gestore che estrae il mio file locale dal db e memorizza nella cache il file fino a quando non cambia il numero di versione.
    • Se cambia (nella configurazione della mia app), la mia class estrae il contenuto del file in base al numero di versione, salvandolo come nuovo record nella mia origine dati, quindi il gestore eseguirà il kick in e servirà la nuova versione.

    In teoria, se il mio codice è scritto correttamente, tutto quello che dovrei fare è cambiare il numero di versione nella mia app config quindi viola! Hai una soluzione di fallback che è automatizzata e non devi mantenere i file fisici sul tuo server.

    Cosa pensano tutti? Forse questo è eccessivo, ma potrebbe essere un metodo elegante per mantenere le tue librerie AJAX.

    Ghianda

    Potresti voler utilizzare il tuo file locale come ultima risorsa.

    Sembra che ora il CDN di jQuery non supporti https. Se così fosse, allora potresti voler caricare da lì prima.

    Quindi, ecco la sequenza: Google CDN => Microsoft CDN => La tua copia locale.

           

    Carica in modo condizionale la versione jQuery più recente / legacy e il fallback:

          
    • Passaggio 1: jQuery non è stato caricato correttamente? (controlla la variabile jQuery )

    Come controllare una variabile non definita in JavaScript

    • Passaggio 2: importa in modo dinamico (il backup) il file javascript

    Come posso includere un file JavaScript in un altro file JavaScript?

    A causa del problema del banning di Google, preferisco usare il cdn di Microsoft http://www.asp.net/ajaxlibrary/cdn.ashx

    Ecco una grande spiegazione su questo!

    Implementa anche i ritardi e i timeout di caricamento!

    http://happyworm.com/blog/2010/01/28/a-simple-and-robust-cdn-failover-for-jquery-14-in-one-line/

    Per coloro che utilizzano ASP.NET MVC 5, aggiungi questo codice nel tuo BundleConfig.cs per abilitare il CDN per jquery:

     bundles.UseCdn = true; Bundle jqueryBundle = new ScriptBundle("~/bundles/jquery", "//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js").Include("~/Scripts/jquery-{version}.js"); jqueryBundle.CdnFallbackExpression = "window.jQuery"; bundles.Add(jqueryBundle); 

    AGGIORNARE:
    Questa risposta si è rivelata sbagliata. Si prega di vedere i commenti per la spiegazione reale.


    Alla maggior parte di voi è stata data una risposta, ma per quanto riguarda la parte finale:

    Quale sarebbe il pericolo che entrambe le copie arrivassero?

    Nessuno davvero. Sprecheresti la larghezza di banda, potresti aggiungere alcuni millisecondi per scaricare una seconda copia inutile, ma non c’è alcun danno reale se entrambi vengono fuori. Ovviamente dovresti evitare questo utilizzando le tecniche sopra menzionate.

    Google Hosted jQuery

    • Se ti interessano i browser più vecchi, soprattutto le versioni di IE precedenti a IE9, questa è la versione jQuery più ampiamente compatibile
      
    • Se non ti interessa di oldie, questo è più piccolo e più veloce:
      

    Piano di backup / fallback!

    • In entrambi i casi, dovresti utilizzare un fallback locale solo nel caso in cui il CDN di Google fallisca (improbabile) o sia bloccato in una posizione dalla quale gli utenti accedono al tuo sito (leggermente più probabile), come l’Iran o qualche volta la Cina.
       

    Riferimento: http://websitespeedoptimizations.com/ContentDeliveryNetworkPost.aspx

    Considero che dovrebbe sfuggire all’ultimo

       

     if (typeof jQuery == 'undefined')) { ... 

    O

     if(!window.jQuery){ 

    Non funzionerà se la versione cdn non è caricata, perché il browser eseguirà questa condizione e durante il download continuerà il resto dei javascript che ha bisogno di jQuery e restituisce un errore. La soluzione era caricare gli script attraverso quella condizione.

        

    Utilizzando la syntax Razor in ASP.NET, questo codice fornisce il supporto fallback e funziona con una radice virtuale:

     @{var jQueryPath = Url.Content("~/Scripts/jquery-1.7.1.min.js");}  

    Oppure fai un aiuto ( panoramica dell’assistente ):

     @helper CdnScript(string script, string cdnPath, string test) { @Html.Raw("" + "") } 

    e usalo in questo modo:

     @CdnScript("jquery-1.7.1.min.js", "ajax/jQuery", "window.jQuery") @CdnScript("jquery.validate.min.js", "ajax/jquery.validate/1.9", "jQuery.fn.validate") 

    Ho creato un Gist che dovrebbe caricare dynamicmente jQuery se non è già stato caricato, e se l’origine fallisce, procede in fallback (uniti da molte risposte): https://gist.github.com/tigerhawkvok/9673154

    Si prega di notare che ho intenzione di mantenere aggiornato Gist ma non questa risposta, per quello che vale!

     /* See https://gist.github.com/tigerhawkvok/9673154 for the latest version */ function cascadeJQLoad(i) { // Use alternate CDNs where appropriate to load jQuery if (typeof(i) != "number") i = 0; // the actual paths to your jQuery CDNs var jq_paths = [ "ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js", "ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.min.js" ]; // Paths to your libraries that require jQuery var dependent_libraries = [ "js/c.js" ]; if (window.jQuery === undefined && i < jq_paths.length) { i++; loadJQ(jq_paths[i], i, dependent_libraries); } if (window.jQuery === undefined && i == jq_paths.length) { // jQuery failed to load // Insert your handler here } } /*** * You shouldn't have to modify anything below here ***/ function loadJQ(jq_path, i, libs) { //load jQuery if it isn't already if (typeof(jq_path) == "undefined") return false; if (typeof(i) != "number") i = 1; var loadNextJQ = function() { var src = 'https:' == location.protocol ? 'https' : 'http'; var script_url = src + '://' + jq_path; loadJS(script_url, function() { if (window.jQuery === undefined) cascadeJQLoad(i); }); } window.onload = function() { if (window.jQuery === undefined) loadNextJQ(); else { // Load libraries that rely on jQuery if (typeof(libs) == "object") { $.each(libs, function() { loadJS(this.toString()); }); } } } if (i > 0) loadNextJQ(); } function loadJS(src, callback) { var s = document.createElement('script'); s.src = src; s.async = true; s.onreadystatechange = s.onload = function() { var state = s.readyState; try { if (!callback.done && (!state || /loaded|complete/.test(state))) { callback.done = true; callback(); } } catch (e) { // do nothing, no callback function passed } }; s.onerror = function() { try { if (!callback.done) { callback.done = true; callback(); } } catch (e) { // do nothing, no callback function passed } } document.getElementsByTagName('head')[0].appendChild(s); } /* * The part that actually calls above */ if (window.readyState) { //older microsoft browsers window.onreadystatechange = function() { if (this.readyState == 'complete' || this.readyState == 'loaded') { cascadeJQLoad(); } } } else { //modern browsers cascadeJQLoad(); } 

    Sebbene la scrittura di document.write("") sembra più semplice per il backoff di jQuery, Chrome fornisce un errore di convalida in quel caso. Quindi preferisco rompere la parola “script”. Quindi diventa più sicuro come sopra.

       

    Per problemi a lungo termine, sarebbe meglio registrare i fallback di JQuery. Nel codice sopra, se il primo CDN non è disponibile, JQuery viene caricato da un altro CDN. Ma potresti voler sapere che CDN errato e rimuoverlo definitivamente. (questo caso è caso eccezionale) Inoltre è meglio registrare i problemi di fallback. Quindi puoi inviare casi errati con AJAX. Poiché JQuery non è definito, è necessario utilizzare vanilla javascript per la richiesta AJAX.

      

    L’impossibilità di caricare la risorsa da un archivio dati esterno fuori dal tuo controllo è difficile. Cercare le funzioni mancanti è totalmente fallace come mezzo per evitare di subire un timeout, come descritto qui: http://www.tech-101.com/support/topic/4499-issues-using-a-cdn/

    Ancora un altro ripiego che sostituisce ajax.googleapis.com con cdnjs.cloudflare.com :

     (function (doc, $) { 'use strict'; if (typeof $ === 'undefined') { var script = doc.querySelector('script[src*="jquery.min.js"]'), src = script.src.replace('ajax.googleapis.com', 'cdnjs.cloudflare.com'); script.parentNode.removeChild(script); doc.write(''); } })(document, window.jQuery || window.Zepto); 
    • Non devi preoccuparti della versione di jQuery
    • Perfetto per Asset Management che non funziona con gli snipe HTML
    • Testato in natura – funziona perfettamente per gli utenti dalla Cina