Beste Möglichkeit, Googles gehostete jQuery zu nutzen, aber bei Google auf meine gehostete Bibliothek zurückgreifen, scheitern

Was wäre eine gute Möglichkeit zu versuchen, die gehostete jQuery bei Google (oder anderen gehosteten Bibliotheken von Google) zu laden, aber meine Kopie von jQuery zu laden, wenn der Google-Versuch fehlschlägt?

Ich sage nicht, dass Google flockig ist. Es gibt Fälle, in denen die Google-Kopie blockiert ist (z. B. im Iran).

Würde ich einen Timer einrichten und nach dem jQuery-Objekt suchen?

Was wäre die Gefahr, dass beide Kopien durchkommen?

Nicht wirklich auf der Suche nach Antworten wie “benutze einfach den Google one” oder “nutze einfach deinen eigenen”. Ich verstehe diese Argumente. Ich verstehe auch, dass die Google-Version wahrscheinlich zwischengespeichert wird. Ich denke über Rückfälle für die Cloud im Allgemeinen nach.


Edit: Dieser Teil hinzugefügt …

Da Google vorschlägt, google.load zu verwenden, um die Ajax-Bibliotheken zu laden, und es einen callback durchführt, wenn das erledigt ist, frage ich mich, ob das der Schlüssel zum Serialisieren dieses Problems ist.

Ich weiß, es klingt ein bisschen verrückt. Ich versuche nur herauszufinden, ob es zuverlässig funktioniert oder nicht.


Update: jQuery wurde jetzt auf Microsofts CDN gehostet.

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

Du kannst es so erreichen:

  

Dies sollte im Ihrer Seite sein und alle jQuery-bereiten Event-Handler sollten sich im , um Fehler zu vermeiden (obwohl es nicht narrensicher ist!).

Ein weiterer Grund, Google-gehostete jQuery nicht zu verwenden, ist, dass der Domainname von Google in einigen Ländern gesperrt ist.

Der einfachste und sauberste Weg, dies bei weitem zu tun:

   

Dies scheint für mich zu funktionieren:

       

hello jQuery

Die functionsweise besteht darin, dass das google Objekt, das http://www.google.com/jsapi aufruft, auf das window geladen wird. Wenn dieses Objekt nicht vorhanden ist, gehen wir davon aus, dass der Zugriff auf Google fehlschlägt. Wenn dies der Fall ist, laden wir eine lokale Kopie mit document.write . (Ich benutze in diesem Fall meinen eigenen Server, bitte benutzen Sie Ihren eigenen Server, um dies zu testen).

Ich window.google.load auch auf das Vorhandensein von window.google.load - ich könnte auch eine Art von Überprüfung machen, um zu sehen, dass Dinge Objekte oder functionen sind, wie es angemessen ist. Aber ich denke, das macht den Trick.

Hier ist nur die Ladelogik, da die Code-Hervorhebung fehlzuschlagen scheint, seit ich die ganze HTML-Seite gepostet habe, die ich getestet habe:

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

Ich muss allerdings sagen, dass ich mir nicht sicher bin, ob Sie sich mit den Google AJAX Libraries APIs herumschlagen sollten, wenn dies für Ihre Website-Besucher von Belang ist.

Fun fact : Ich habe anfangs versucht, einen try..catch-Block dafür in verschiedenen Versionen zu verwenden, konnte aber keine so saubere Kombination finden. Ich wäre daran interessiert, andere Implementierungen dieser Idee als Übung zu sehen.

Wenn Sie modernizr.js auf Ihrer Site eingebettet haben, können Sie die integrierte Datei yepnope.js verwenden, um Ihre Skripte asynchron zu laden – unter anderem jQuery (mit 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(); } }]); 

Dies lädt jQuery von der Google-CDN. Danach wird geprüft, ob jQuery erfolgreich geladen wurde. Wenn nicht (“nein”), wird die lokale Version geladen. Auch Ihre persönlichen Skripte werden geladen – die “beide” zeigen an, dass der Ladeprozess unabhängig vom Testergebnis gestartet wird.

Wenn alle Ladeprozesse abgeschlossen sind, wird eine function ausgeführt, im Fall ‘MyApp.init’.

Ich persönlich bevorzuge diese Art des asynchronen Ladens von Skripten. Und da ich mich bei der Erstellung einer Site auf die Feature-Tests von modernizr stütze, habe ich sie trotzdem auf der Site eingebettet. Es gibt also keinen Overhead.

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

Nachdem Sie versucht haben, die Google-Kopie aus dem CDN zu übernehmen.

In HTML5 müssen Sie das Typattribut nicht festlegen.

Sie können auch …

 window.jQuery || document.write(' 

Es gibt hier einige großartige Lösungen, aber ich würde gerne einen Schritt weiter gehen, wenn es um die lokale Datei geht.

In einem Szenario, in dem Google fehlschlägt, sollte es eine lokale Quelle laden, aber möglicherweise ist eine physische Datei auf dem Server nicht unbedingt die beste Option. Ich führe das auf, weil ich derzeit dieselbe Lösung implementiere, nur möchte ich auf eine lokale Datei zurückgreifen, die von einer Datenquelle generiert wird.

Meine Gründe dafür sind, dass ich ein bisschen Verstand haben möchte, wenn es darum geht, zu verfolgen, was ich von Google lade und was ich auf dem lokalen Server habe. Wenn ich die Versionen ändern möchte, möchte ich meine lokale Kopie mit dem synchronisieren, was ich von Google laden möchte. In einer Umgebung, in der es viele Entwickler gibt, wäre der beste Weg, diesen process zu automatisieren, so dass man nur eine Versionsnummer in einer Konfigurationsdatei ändern müsste.

Hier ist meine vorgeschlagene Lösung, die in der Theorie funktionieren sollte:

  • In einer Anwendungskonfigurationsdatei speichere ich drei Dinge: die absolute URL für die Bibliothek, die URL für die JavaScript-API und die Versionsnummer
  • Schreiben Sie eine class, die den Dateiinhalt der Bibliothek selbst abruft (holt die URL aus der App-Konfiguration), speichert sie in meiner Datenquelle mit dem Namen und der Versionsnummer
  • Schreiben Sie einen Handler, der meine lokale Datei aus der database holt und die Datei zwischenspeichert, bis sich die Versionsnummer ändert.
  • Wenn es sich ändert (in meiner App-Konfiguration), zieht meine class den Inhalt der Datei basierend auf der Versionsnummer, speichert sie als neuen Datensatz in meiner Datenquelle, dann tritt der Handler ein und liefert die neue Version.

In der Theorie, wenn mein Code richtig geschrieben ist, alles, was ich tun müsste, ist die Versionsnummer in meiner App Config dann Viola zu ändern! Sie haben eine Fallback-Lösung, die automatisiert ist, und Sie müssen keine physischen Dateien auf Ihrem Server verwalten.

Was denkt jeder? Vielleicht ist das Overkill, aber es könnte eine elegante Methode zur Pflege Ihrer AJAX-Bibliotheken sein.

Eichel

Möglicherweise möchten Sie Ihre lokale Datei als letzten Ausweg verwenden.

Scheint ab jetzt jQuery’s eigene CDN unterstützt kein https. Wenn es Sie tat, dann möchten Sie vielleicht zuerst von dort laden.

Also hier ist die Reihenfolge: Google CDN => Microsoft CDN => Ihre lokale Kopie.

       

Laden Sie die letzte / ältere jQuery-Version und den Fallback mit der folgenden Bedingung:

      
  • Schritt 1: Wurde jQuery nicht geladen? (Überprüfen Sie die jQuery Variable)

So prüfen Sie eine nicht definierte Variable in JavaScript

  • Schritt 2: Dynamische Import (die Backup) Javascript Datei

Wie schließe ich eine JavaScript-Datei in eine andere JavaScript-Datei ein?

Wegen des Bannproblems von Google bevorzuge ich die Verwendung von Microsoft’s cdn http://www.asp.net/ajaxlibrary/cdn.ashx

Hier ist eine großartige Erklärung dazu!

Implementiert auch Ladeverzögerungen und Timeouts!

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

Wenn Sie ASP.NET MVC 5 verwenden, fügen Sie diesen Code in BundleConfig.cs hinzu, um das CDN für jQuery zu aktivieren:

 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); 

AKTUALISIEREN:
Diese Antwort stellte sich als falsch heraus. Bitte beachten Sie die Kommentare für die eigentliche Erklärung.


Die meisten von Ihnen Frage wurde beantwortet, aber wie für den letzten Teil:

Was wäre die Gefahr, dass beide Kopien durchkommen?

Keine wirklich. Sie würden Bandbreite verschwenden, könnten einige Millisekunden hinzufügen und eine zweite nutzlose Kopie herunterladen, aber es gibt keinen wirklichen Schaden, wenn sie beide durchkommen. Sie sollten dies natürlich mit den oben genannten Techniken vermeiden.

Google Hosted jQuery

  • Wenn Sie ältere Browser, hauptsächlich Versionen von IE vor IE9, interessieren, ist dies die am weitesten verbreitete jQuery-Version
  
  • Wenn Sie sich nicht um OldIE kümmern, ist dieser kleiner und schneller:
  

Backup / Ausweichplan!

  • In jedem Fall sollten Sie ein Fallback auf Local für den Fall verwenden, dass das Google CDN fehlschlägt (unwahrscheinlich) oder an einem Ort blockiert wird, auf den Ihre Nutzer von Ihrer Seite aus zugreifen (etwas wahrscheinlicher), wie der Iran oder manchmal China.
   

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

Ich denke, dass sollte das letzte

   

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

Oder

 if(!window.jQuery){ 

functioniert nicht, wenn die cdn-Version nicht geladen ist, weil der Browser diese Bedingung durchläuft und währenddessen noch den Rest von Javascripts herunterlädt, die jQuery benötigen, und es gibt einen Fehler zurück. Die Lösung bestand darin, Skripte über diese Bedingung zu laden.

    

Mit der Razor-Syntax in ASP.NET bietet dieser Code Fallback-Unterstützung und arbeitet mit einem virtuellen Stammverzeichnis:

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

Oder mache einen Helfer ( Helferübersicht ):

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

und benutze es so:

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

Ich habe einen Gist erstellt, der jQuery dynamisch laden sollte, wenn er nicht bereits geladen ist, und wenn die Quelle fehlschlägt, geht es auf Fallbacks (zusammengefügt aus vielen Antworten): https://gist.github.com/tigerhawkvok/9673154

Bitte beachten Sie, dass ich beabsichtige, den Gist auf dem neuesten Stand zu halten, aber nicht diese Antwort, denn was es wert ist!

 /* 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(); } 

Obwohl das Schreiben von document.write("") für jQuery-Backoff einfacher scheint, gibt Chrome in diesem Fall einen validationserrors aus. Also bevorzuge ich das “Skript” Wort zu brechen. So wird es sicherer wie oben.

   

Bei langfristigen Problemen wäre es besser, JQuery-Fallbacks zu protokollieren. Wenn in dem obigen Code das erste CDN nicht verfügbar ist, wird JQuery von einem anderen CDN geladen. Aber Sie könnten das errorshafte CDN wissen wollen und es dauerhaft entfernen. (Dieser Fall ist ein sehr ungewöhnlicher Fall.) Es ist auch besser, Fallback-Probleme zu protokollieren. So können Sie errorshafte Fälle mit AJAX senden. Da JQuery nicht definiert ist, sollten Sie Vanille-Javascript für AJAX-Anfrage verwenden.

  

Das Unvermögen, die Ressource von einem externen Datenspeicher zu laden, der nicht von Ihnen kontrolliert werden kann, ist schwierig. Auf der Suche nach fehlenden functionen ist absolut irreführend, um ein Timeout zu vermeiden, wie hier beschrieben: http://www.tech-101.com/support/topic/4499-issues-using-a-cdn/

Noch ein Fallback, das ajax.googleapis.com durch cdnjs.cloudflare.com ersetzt :

 (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); 
  • Sie müssen sich nicht um die jQuery-Version kümmern
  • Perfekt für Asset Management, das mit HTML-Snips nicht funktioniert
  • Getestet in der Wildnis – perfekt für Anwender aus China