it-swarm-eu.dev

Nejlepší způsob, jak používat Google hostil jQuery, ale spadnout zpět do mé hostované knihovny na Google selhat

Jaký by byl dobrý způsob, jak se pokusit načíst hostovaný jQuery na Google (nebo jiných hostovaných librách Google), ale načíst moji kopii jQuery, pokud se pokus Google nezdaří?

Neříkám, že Google je šupinatý. Existují případy, kdy je kopie Google zablokována (například v Íránu).

Nastavil bych časovač a zkontroloval objekt jQuery?

Jaké by bylo nebezpečí, že obě kopie projdou?

Nehledáte odpovědi, jako je například „stačí použít Google“ nebo „stačí použít svůj vlastní“. Chápu ty argumenty. Také chápu, že uživatel má pravděpodobně uloženou verzi Google. Přemýšlím o haváriích pro mrak obecně.


Upravit: Tato část byla přidána ...

Vzhledem k tomu, Google navrhuje použít google.load načíst iax knihovny, a to provádí zpětné volání, když jsem udělal, přemýšlím, jestli je to klíč k serializaci tohoto problému.

Vím, že to zní trochu šíleně. Jen se snažím zjistit, jestli to může být provedeno spolehlivým způsobem.


Aktualizace: jQuery je nyní hostováno na CDN společnosti Microsoft.

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

1001
Nosredna

Můžete toho dosáhnout takto:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script>
   window.jQuery || document.write('<script src="/path/to/your/jquery"><\/script>');
</script>

To by mělo být ve vaší stránce <head> a jakékoli obslužné rutiny událostí jQuery ready by měly být v <body>, aby se předešlo chybám (i když to není bláznivé!).

Dalším důvodem pro to, že není používat Google hostované jQuery je, že v některých zemích je název domény Google zakázán.

793
Rony

Nejjednodušší a nejčistší způsob, jak toho dosáhnout:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="path/to/your/jquery"><\/script>')</script>
333
BenjaminRH

Zdá se, že to funguje pro mě:

<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
// has the google object loaded?
if (window.google && window.google.load) {
    google.load("jquery", "1.3.2");
} else {
    document.write('<script type="text/javascript" src="http://joecrawford.com/jquery-1.3.2.min.js"><\/script>');
}
window.onload = function() {
    $('#test').css({'border':'2px solid #f00'});
};
</script>
</head>
<body>
    <p id="test">hello jQuery</p>
</body>
</html>

Způsob, jakým to funguje, je použít objekt google, který volá http://www.google.com/jsapi load do objektu window. Pokud tento objekt není přítomen, předpokládáme, že přístup k Googlu selhává. Pokud tomu tak je, načteme lokální kopii pomocí document.write. (V tomto případě používám svůj vlastní server, pro testování použijte svůj vlastní server).

Také testuji na přítomnost window.google.load - mohl bych také provést kontrolu typeof, aby se zjistilo, že věci jsou objekty nebo funkce podle potřeby. Ale myslím, že to dělá trik.

Zde je pouze logika načítání, protože zvýraznění kódu selhalo, protože jsem odeslal celou stránku HTML, kterou jsem testoval:

if (window.google && window.google.load) {
    google.load("jquery", "1.3.2");
} else {
    document.write('<script type="text/javascript" src="http://joecrawford.com/jquery-1.3.2.min.js"><\/script>');
}

I když musím říci, nejsem si jistý, že pokud se jedná o váš zájem návštěvníků vašich stránek, měli byste si hrát s Google AJAX knihovnami API vůbec.

Fun fact: Snažil jsem se pro to zpočátku použít testovací blok v různých verzích, ale nemohl jsem najít kombinaci, která by byla stejně čistá. Zajímalo by mě, kdybych viděl další implementace této myšlenky, čistě jako cvičení.

75
artlung

Pokud máte na svých stránkách vloženy prvky modernizr.js, můžete pomocí vestavěného nástroje yepnope.js načíst skripty asynchronně - mimo jiné jQuery (s nouzovým).

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

Načte se jQuery z Google-cdn. Poté je zaškrtnuto, pokud byl jQuery úspěšně načten. Pokud ne ("nope"), je načtena místní verze. Také jsou načteny vaše osobní skripty - „oba“ znamenají, že proces načítání je odvozen nezávisle na výsledku testu.

Po dokončení všech zatěžovacích procesů se provede funkce v případě „MyApp.init“.

Osobně dávám přednost tomuto způsobu načítání asynchronního skriptu. A jak jsem se spoléhat na funkce-testy poskytované modernizr při stavbě webu, mám ji vložen na místě stejně. Takže vlastně není žádná režie.

30
Emanuel Kluge

Tam jsou některé skvělé řešení zde, ale budu chtít, aby to o krok dále, pokud jde o místní soubor.

Ve scénáři, kdy Google selže, by měl načíst lokální zdroj, ale možná fyzický soubor na serveru nemusí být tou nejlepší volbou. Přinesu to, protože jsem v současné době provádí stejné řešení, jen chci spadnout do místního souboru, který dostane generován zdrojem dat.

Moje důvody pro to je, že chci mít nějaký kus mysli, pokud jde o sledování toho, co jsem zatížení od Google vs to, co mám na místním serveru. Pokud chci změnit verze, chci ponechat svou místní kopii synchronizovanou s tím, co se pokouším načíst ze služby Google. V prostředí, kde je mnoho vývojářů, se domnívám, že nejlepším přístupem by bylo automatizovat tento proces tak, aby bylo nutné změnit číslo verze v konfiguračním souboru.

Zde je mé navrhované řešení, které by mělo fungovat teoreticky:

  • V konfiguračním souboru aplikace uložím 3 věci: absolutní adresu URL knihovny, adresu URL rozhraní JavaScript a číslo verze
  • Napište třídu, která získá obsah souboru samotné knihovny (získá adresu URL z aplikace config), uloží ji v mém zdroji dat s názvem a číslem verze
  • Napište popisovač, který vytáhne můj místní soubor z db a uloží soubor do paměti, dokud se číslo verze nezmění.
  • Pokud se to změní (v mé aplikaci config), moje třída vytáhne obsah souboru na základě čísla verze, uloží jej jako nový záznam v mém zdroji dat, pak se psovod rozbalí a podá novou verzi.

Teoreticky, pokud je můj kód napsán správně, vše, co bych musel udělat, je změnit číslo verze v mé aplikaci config pak viola! Máte nouzové řešení, které je automatizované, a nemusíte udržovat fyzické soubory na serveru.

Co si všichni myslí? Možná je to přehnané, ale mohlo by to být elegantní způsob udržování knihoven AJAX.

Žalud

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

}

Po pokusu o vložení kopie Google z CDN.

V HTML5 nemusíte nastavit atribut type.

Můžete také použít ...

window.jQuery || document.write('<script src="/libs/jquery.js"><\/script>');
20
alex

Můžete použít místní soubor jako poslední možnost.

Zdá se, že jQuery vlastní CDN nepodporuje https. Pokud jste to pak mohli chtít načíst odtud první.

Tady je pořadí: Google CDN => Microsoft CDN => Vaše místní kopie.

<!-- load jQuery from Google's CDN -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 
<!-- fallback to Microsoft's Ajax CDN -->
<script> window.jQuery || document.write('<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.3.min.js">\x3C/script>')</script> 
<!-- fallback to local file -->
<script> window.jQuery || document.write('<script src="Assets/jquery-1.8.3.min.js">\x3C/script>')</script> 
9
Edward Olamisan

Podmíněně načíst nejnovější verzi/jQuery a záložní verzi:

<!--[if lt IE 9]>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="/public/vendor/jquery-legacy/dist/jquery.min.js">\x3C/script>')</script>
<![endif]-->
<!--[if gte IE 9]><!-->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="/public/vendor/jquery/dist/jquery.min.js">\x3C/script>')</script>
<!--<![endif]-->
6
neiker

Vzhledem k tomu, že Google je problém s banováním, raději používám cdn společnosti Microsoft http://www.asp.net/ajaxlibrary/cdn.ashx

5
Serdar
  • Krok 1: Nepodařilo se načíst soubor jQuery? (zkontrolujte proměnnou jQuery)

Jak zkontrolovat nedefinovanou proměnnou v jazyce JavaScript

  • Krok 2: Dynamicky importujte soubor zálohy (záloha)

Jak vložím soubor JavaScript do jiného souboru JavaScript?

5
ninjagecko

Pro ty lidi, kteří používají ASP.NET MVC 5, přidejte tento kód do vašeho BundleConfig.cs, abyste povolili CDN pro 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);
4

AKTUALIZACE:
Tato odpověď se ukázala být chybná. Podívejte se prosím na komentáře pro skutečné vysvětlení.


Většina z vás byla zodpovězena, ale jako poslední část:

Jaké by bylo nebezpečí, že obě kopie projdou?

Žádný opravdu. Ztratili byste šířku pásma, mohli byste přidat nějaké milisekundy, abyste si stáhli druhou zbytečnou kopii, ale pokud to oba projdou, není to skutečné poškození. Měli byste se tomu vyhnout použitím výše uvedených technik.

4
WhyNotHugo

Zde je skvělé vysvětlení!

Také implementuje zpoždění načítání a časové limity!

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

4
Stuart.Sklinar

Udělal jsem Gist, který by měl dynamicky načítat jQuery, pokud ještě není načten, a pokud zdroj selže, pokračuje na nouzové situace (sešité z mnoha odpovědí): https://Gist.github.com/tigerhawkvok/9673154

Vezměte prosím na vědomí, že plánuji udržet Gist aktualizovaný, ale ne tuto odpověď, za to, co stojí za to!

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

Domnívám se, že by mělo uniknout poslední <do x3 v řetězci. Když prohlížeč uvidí, považuje to za konec bloku skriptu (protože syntaktický analyzátor HTML nemá představu o JavaScriptu, nemůže rozlišovat mezi něčím, co se právě objevuje v řetězci, a něčím, co vlastně znamená ukončit skript živel). Takže objevování se doslova v JavaScriptu, který je uvnitř HTML stránky (v nejlepším případě) způsobí chyby, a (v nejhorším případě) obrovskou bezpečnostní díru.

<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js"></script>
<script>window.jQuery || document.write('<script src="js/jquery-2.0.0.min.js">\x3C/script>')</script>
2
JKhuang

Google Hosted jQuery

  • Pokud se staráte o starší prohlížeče, především verze IE před IE9, jedná se o nejrozšířenější verzi jQuery
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  • Pokud se nestaráte o oldIE, je tento menší a rychlejší:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

Backup/Fallback Plan!

  • Ať tak či onak, měli byste použít nouzový režim pro místní jen v případě, že Google CDN selže (nepravděpodobně) nebo je zablokován v místě, kde uživatelé přistupují na vaše stránky z (o něco pravděpodobnější), jako je Írán nebo někdy Čína.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>if (!window.jQuery) { document.write('<script src="/path/to/your/jquery"><\/script>'); }
</script>

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

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

Nebo

if(!window.jQuery){

Nebude fungovat, pokud není načtena verze cdn, protože prohlížeč bude procházet touto podmínkou a během ní bude stále stahovat zbytek javascriptů, které potřebují jQuery a vrátí chybu. Řešením bylo načíst skripty prostřednictvím této podmínky.

    <script src="http://WRONGPATH.code.jquery.com/jquery-1.4.2.min.js" type="text/javascript"></script><!--  WRONGPATH for test-->
  <script type="text/javascript">
  function loadCDN_or_local(){
    if(!window.jQuery){//jQuery not loaded, take a local copy of jQuery and then my scripts
      var scripts=['local_copy_jquery.js','my_javascripts.js'];
      for(var i=0;i<scripts.length;i++){
      scri=document.getElementsByTagName('head')[0].appendChild(document.createElement('script'));
      scri.type='text/javascript';
      scri.src=scripts[i];
    }
  }
  else{// jQuery loaded can load my scripts
    var s=document.getElementsByTagName('head')[0].appendChild(document.createElement('script'));
    s.type='text/javascript';
    s.src='my_javascripts.js';
  }
  }
  window.onload=function(){loadCDN_or_local();};
  </script>
2
Mirek Komárek

Přestože psaní document.write("<script></script>") se zdá být pro backoff jQuery jednodušší, Chrome v tomto případě udělí chybu ověření. Takže dávám přednost lámání "skriptu" Wordu. Tak se stává bezpečnější, jako je uvedeno výše.

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.1.min.js"></script>
<script>if (typeof jQuery === "undefined") {
   window.jqFallback = true;
   document.write("<scr"+"ipt src='http://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js'></scr"+"ipt>");
} </script>

Pro dlouhodobé problémy by bylo lepší protokolovat JQuery. Pokud výše uvedený kód není k dispozici, je první disk CDN načten z jiného disku CDN. Ale mohli byste vědět, že to chybné CDN a odstranit trvale. (tento případ je velmi výjimečný případ) Také je lepší přihlásit záložní problémy. Takže můžete poslat chybné případy s AJAX. Vzhledem k tomu, že JQuery není definován, měli byste pro požadavek AJAX použít Vanilla javascript.

<script type="text/javascript">
    if (typeof jQuery === 'undefined' || window.jqFallback == true) {
        // XMLHttpRequest for IE7+, Firefox, Chrome, Opera, Safari
        // ActiveXObject for IE6, IE5
        var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
        var url = window.jqFallback == true ? "/yourUrl/" : "/yourUrl2/";
        xmlhttp.open("POST", url, true);
        xmlhttp.send();
    }
</script>
1
trante

Neschopnost načíst prostředek z externího úložiště dat mimo kontrolu je obtížné. Hledání chybějících funkcí je naprosto klamné jako prostředek, jak se vyhnout timeoutu, jak je zde popsáno: http://www.tech-101.com/support/topic/4499-issues-using-a -cdn/

1
jobeard

Pomocí syntaxe Razor v ASP.NET tento kód poskytuje nouzovou podporu a pracuje s virtuálním kořenem:

@{var jQueryPath = Url.Content("~/Scripts/jquery-1.7.1.min.js");}
<script type="text/javascript">
    if (typeof jQuery == 'undefined')
        document.write(unescape("%3Cscript src='@jQueryPath' type='text/javascript'%3E%3C/script%3E"));
</script>

Nebo vytvořte pomocníka ( přehled pomocníka ):

@helper CdnScript(string script, string cdnPath, string test) {
    @Html.Raw("<script src=\"http://ajax.aspnetcdn.com/" + cdnPath + "/" + script + "\" type=\"text/javascript\"></script>" +
        "<script type=\"text/javascript\">" + test + " || document.write(unescape(\"%3Cscript src='" + Url.Content("~/Scripts/" + script) + "' type='text/javascript'%3E%3C/script%3E\"));</script>")
}

a použijte to takto:

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

Můžete použít kód jako:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>window.jQuery || document.write('<script type="text/javascript" src="./scripts/jquery.min.js">\x3C/script>')</script>

Existují však také knihovny, pomocí kterých můžete nastavit několik možných nouzových situací pro skripty a optimalizovat proces načítání:

  • basket.js
  • RequireJS
  • yepnope

Příklady:

basket.js Myslím, že nejlepší varianta je zatím. Bude cach váš skript v localStorage, který urychlí další načítání. Nejjednodušší volání:

basket.require({ url: '/path/to/jquery.js' });

Tím se vrátí slib a můžete provést další volání na chybu nebo načíst závislosti na úspěchu:

basket
    .require({ url: '/path/to/jquery.js' })
    .then(function () {
        // Success
    }, function (error) {
        // There was an error fetching the script
        // Try to load jquery from the next cdn
    });

RequireJS

requirejs.config({
    enforceDefine: true,
    paths: {
        jquery: [
            '//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min',
            //If the CDN location fails, load from this location
            'js/jquery-2.0.0.min'
        ]
    }
});

//Later
require(['jquery'], function ($) {
});

yepnope

yepnope([{
  load: 'http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js',
  complete: function () {
    if (!window.jQuery) {
      yepnope('js/jquery-2.0.0.min.js');
    }
  }
}]);

Ještě další záložní místo, které nahrazuje ajax.googleapis.com with 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('<script src="' + src + '"></script>');
    }
})(document, window.jQuery || window.Zepto);
  • Můžete se držet verze jQuery zadáním v řetězci
  • Ideální pro správu aktiv, která nefunguje s HTML výstřižky
  • Testováno ve volné přírodě - ideální pro uživatele z Číny
0
redaxmedia