Meilleur moyen d’utiliser jQuery hébergé par Google, mais retour à ma bibliothèque hébergée sur Google échoué

Quelle serait une bonne façon de tenter de charger jQuery hébergé chez Google (ou d’autres bibliothèques hébergées par Google ), mais de charger ma copie de jQuery si la tentative de Google échoue?

Je ne dis pas que Google est flaky. Il y a des cas où la copie de Google est bloquée (apparemment en Iran, par exemple).

Est-ce que je configurerais une timer et vérifierais l’object jQuery?

Quel serait le danger de voir les deux copies arriver?

Pas vraiment à la recherche de réponses comme “utilisez simplement celle de Google” ou “utilisez simplement la vôtre”. Je comprends ces arguments. Je comprends également que l’utilisateur est susceptible d’avoir la version de Google mise en cache. Je pense aux solutions de rechange pour le cloud en général.


Edit: Cette partie ajoutée …

Étant donné que Google suggère d’utiliser google.load pour charger les bibliothèques ajax, et qu’il effectue un rappel une fois l’opération terminée, je me demande si c’est la clé de la sérialisation de ce problème.

Je sais que ça semble un peu fou. J’essaie simplement de savoir si cela peut être fait de manière fiable ou non.


Mise à jour: jQuery est maintenant hébergé sur le CDN de Microsoft.

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

Vous pouvez y arriver comme ceci:

  

Cela devrait être dans votre page et tout gestionnaire d'événement jQuery ready devrait se trouver dans le pour éviter les erreurs (bien que ce ne soit pas infaillible!).

Une autre raison de ne pas utiliser jQuery hébergé par Google est que, dans certains pays, le nom de domaine de Google est interdit.

Le moyen le plus simple et le plus propre de le faire de loin:

   

Cela semble fonctionner pour moi:

       

hello jQuery

La façon dont cela fonctionne est d'utiliser l'object google qui appelle http://www.google.com/jsapi charge sur l'object window . Si cet object n'est pas présent, nous supposons que l'access à Google échoue. Si c'est le cas, nous chargeons une copie locale à l'aide de document.write . (J'utilise mon propre serveur dans ce cas, veuillez utiliser le vôtre pour le tester).

Je teste également la présence de window.google.load - Je pourrais également faire une vérification de type pour voir que les objects sont des objects ou des fonctions appropriés. Mais je pense que cela fait l'affaire.

Voici juste la logique de chargement, car la mise en évidence du code semble échouer depuis que j'ai posté toute la page HTML que je testais:

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

Bien que je dois dire, je ne suis pas sûr que si cela est un souci pour les visiteurs de votre site, vous devriez jouer avec l' API des bibliothèques Google AJAX .

Fait amusant : j'ai d'abord essayé d'utiliser un bloc try..catch dans différentes versions, mais je n'ai pas trouvé de combinaison aussi nette. Je serais intéressé de voir d'autres implémentations de cette idée, uniquement comme un exercice.

Si vous avez modernizr.js incorporé sur votre site, vous pouvez utiliser le fichier yepnope.js intégré pour charger vos scripts de manière asynchrone – entre autres jQuery (avec repli).

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

Cela charge jQuery à partir de Google-cdn. Ensuite, il est vérifié si jQuery a été chargé avec succès. Sinon (“non”), la version locale est chargée. Vos scripts personnels sont également chargés – les “deux” indiquent que le processus de chargement est initié indépendamment du résultat du test.

Lorsque tous les processus de chargement sont terminés, une fonction est exécutée, dans le cas «MyApp.init».

Personnellement, je préfère cette méthode de chargement de script asynchrone. Et comme je me fie aux tests de fonctionnalités fournis par modernizr lors de la construction d’un site, je l’ai de toute façon intégré au site. Donc, il n’y a pas de frais généraux.

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

Après avoir tenté d’inclure la copie de Google depuis le CDN.

En HTML5, vous n’avez pas besoin de définir l’atsortingbut type .

Vous pouvez aussi utiliser…

 window.jQuery || document.write(' 

Il existe d’excellentes solutions, mais je voudrais aller plus loin en ce qui concerne le fichier local.

Dans un scénario où Google échoue, il doit charger une source locale, mais peut-être qu’un fichier physique sur le serveur n’est pas nécessairement la meilleure option. Je soulève cette question car je suis en train d’implémenter la même solution, mais je veux seulement utiliser un fichier local généré par une source de données.

Mes raisons pour cela sont que je veux avoir un peu d’esprit en ce qui concerne le suivi de ce que je charge de Google par rapport à ce que j’ai sur le serveur local. Si je veux changer de version, je veux garder ma copie locale synchronisée avec ce que j’essaie de charger depuis Google. Dans un environnement où il existe de nombreux développeurs, je pense que la meilleure approche serait d’automatiser ce processus afin de ne modifier que le numéro de version dans un fichier de configuration.

Voici ma solution proposée qui devrait fonctionner en théorie:

  • Dans un fichier de configuration d’application, je vais stocker 3 éléments: l’URL absolue de la bibliothèque, l’URL de l’API JavaScript et le numéro de version.
  • Ecrivez une classe qui récupère le contenu de la bibliothèque (récupère l’URL de la configuration de l’application), la stocke dans ma source de données avec le nom et le numéro de version
  • Ecrivez un gestionnaire qui extrait mon fichier local de la firebase database et met le fichier en cache jusqu’à ce que le numéro de version change.
  • Si cela change (dans la configuration de mon application), ma classe va extraire le contenu du fichier en fonction du numéro de version, l’enregistrer en tant que nouvel enregistrement dans ma source de données, puis le gestionnaire activera la nouvelle version.

En théorie, si mon code est écrit correctement, il me suffirait de changer le numéro de version dans la configuration de mon application puis d’alto! Vous avez une solution de secours qui est automatisée et vous n’avez pas besoin de conserver des fichiers physiques sur votre serveur.

Qu’est-ce que tout le monde pense? Peut-être que c’est excessif, mais cela pourrait être une méthode élégante pour maintenir vos bibliothèques AJAX.

Gland

Vous voudrez peut-être utiliser votre fichier local en dernier recours.

Semble dès maintenant le propre CDN de jQuery ne supporte pas https. Si c’est le cas, alors vous voudrez peut-être charger le premier.

Voici donc la séquence: Google CDN => Microsoft CDN => Votre copie locale.

       

Charger conditionnellement la dernière version de jQuery / legacy et solution de repli:

      
  • Étape 1: jQuery n’a-t-il pas pu être chargé? (cochez la variable jQuery )

Comment vérifier une variable non définie en JavaScript

  • Étape 2: Importer dynamicment (la sauvegarde) le fichier javascript

Comment inclure un fichier JavaScript dans un autre fichier JavaScript?

En raison du problème d’interdiction de Google, je préfère utiliser le cdn de Microsoft http://www.asp.net/ajaxlibrary/cdn.ashx

Voici une bonne explication à ce sujet!

Implémente également les délais et les délais de chargement!

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

Pour les personnes utilisant ASP.NET MVC 5, ajoutez ce code dans votre BundleConfig.cs pour permettre au CDN de 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); 

METTRE À JOUR:
Cette réponse s’est avérée fausse. S’il vous plaît voir les commentaires pour la vraie explication.


La plupart de vos questions ont reçu une réponse, mais pour la dernière partie:

Quel serait le danger de voir les deux copies arriver?

Aucun vraiment. Vous perdriez de la bande passante, vous pourriez append quelques millisecondes en téléchargeant une deuxième copie inutile, mais il n’y a pas de préjudice réel si les deux versions sont traitées. Évidemment, vous devriez éviter cela en utilisant les techniques mentionnées ci-dessus.

Google Hosted jQuery

  • Si vous vous souciez des navigateurs plus anciens, principalement des versions d’IE antérieures à IE9, il s’agit de la version jQuery la plus compatible.
  
  • Si vous ne vous souciez pas de oldIE, celui-ci est plus petit et plus rapide:
  

Plan de sauvegarde / secours!

  • Dans tous les cas, vous devez utiliser une solution de remplacement au cas où le CDN de Google échouerait (improbable) ou serait bloqué dans un emplacement auquel vos utilisateurs accèdent (légèrement plus probable), comme l’Iran ou parfois la Chine.
   

Référence: http://websitespeedoptimizations.com/ContentDeliveryNetworkPost.aspx

Je considère que cela devrait échapper à la dernière <à \ x3C dans la chaîne. Lorsque le navigateur voit, il considère que ceci est la fin du bloc de script (puisque l'analyseur HTML n'a aucune idée de JavaScript, il ne peut pas faire la distinction entre quelque chose qui apparaît dans une chaîne et quelque chose qui a pour but de terminer le script) élément). Donc, apparaître littéralement dans JavaScript à l'intérieur d'une page HTML (dans le meilleur des cas) provoquera des erreurs et, dans le pire des cas, constituera une énorme faille de sécurité.

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

Ou

 if(!window.jQuery){ 

Ne fonctionnera pas si la version cdn n’est pas chargée, car le navigateur fonctionnera à travers cette condition et pendant qu’il télécharge encore le rest des javascripts qui nécessitent jQuery et qu’il renvoie une erreur. La solution consistait à charger des scripts via cette condition.

    

En utilisant la syntaxe Razor dans ASP.NET, ce code fournit une prise en charge de secours et fonctionne avec une racine virtuelle:

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

Ou faire une aide ( aperçu de l’aide ):

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

et l’utiliser comme ceci:

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

J’ai fait un Gist qui devrait charger dynamicment jQuery s’il n’est pas déjà chargé, et si la source échoue, il procède à un repli (assemblé à partir de nombreuses réponses): https://gist.github.com/tigerhawkvok/9673154

S’il vous plaît noter que je prévois de garder le Gist mis à jour, mais pas cette réponse, pour ce que ça vaut!

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

Bien que l’écriture de document.write("") semble plus facile pour le backoff jQuery, Chrome émet une erreur de validation sur ce cas. Je préfère donc casser le mot “script”. Donc, cela devient plus sûr comme ci-dessus.

   

Pour les problèmes à long terme, il serait préférable de se connecter aux solutions de remplacement JQuery. Dans le code ci-dessus, si le premier CDN n’est pas disponible, JQuery est chargé à partir d’un autre CDN. Mais vous pourriez vouloir connaître ce CDN erroné et le supprimer définitivement. (ce cas est très exceptionnel) Il est également préférable de journaliser les problèmes de repli. Vous pouvez donc envoyer des cas erronés avec AJAX. Parce que JQuery n’est pas défini, vous devez utiliser le javascript pour la requête AJAX.

  

L’incapacité de charger la ressource à partir d’un magasin de données externe hors de votre contrôle est difficile. La recherche de fonctions manquantes est totalement fausse pour éviter de subir un délai d’attente, comme décrit ici: http://www.tech-101.com/support/topic/4499-issues-using-a-cdn/

Encore un autre repli qui remplace ajax.googleapis.com avec cdnjs.cloudflare.com :

 (function (doc, $) { 'use ssortingct'; 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); 
  • Vous n’avez pas à vous soucier de la version de jQuery
  • Parfait pour la gestion des actifs qui ne fonctionne pas avec les snips HTML
  • Testé dans la nature – fonctionne parfaitement pour les utilisateurs de Chine