Google'ın barındırdığı jQuery'yi kullanmanın en iyi yolu, ancak Google'daki barındırılan kütüphaneme geri dönme başarısız


1016

Barındırılan jQuery'yi Google'a (veya diğer Google tarafından barındırılan kütüphanelere) yüklemeye çalışmanın, ancak Google girişimi başarısız olursa jQuery kopyamı yüklemenin iyi bir yolu nedir ?

Google'ın lapa lapa olduğunu söylemiyorum. Google kopyanın engellendiği durumlar var (örneğin İran'da).

Bir zamanlayıcı ayarlayıp jQuery nesnesini kontrol eder miyim?

Her iki kopyanın da gelmesi tehlikesi ne olabilir?

"Yalnızca Google'ı kullanın" veya "yalnızca kendi yanıtınızı kullanın" gibi yanıtlar aramamak. Bu argümanları anlıyorum. Ayrıca kullanıcının Google sürümünün önbelleğe alınmasının muhtemel olduğunu da anlıyorum. Genel olarak bulut için geri dönüşler düşünüyorum.


Düzenle: Bu bölüm eklendi ...

Google, ajax kitaplıklarını yüklemek için google.load kullanılmasını önerdiğinden ve tamamlandığında bir geri arama gerçekleştirdiğinden, bu sorunun serileştirilmesinin anahtarı olup olmadığını merak ediyorum.

Biraz çılgınca geldiğini biliyorum. Sadece güvenilir bir şekilde yapılıp yapılamayacağını anlamaya çalışıyorum.


Güncelleştirme: jQuery artık Microsoft'un CDN'sinde barındırılıyor.

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


9
Tabii ki ilk cevap "Google tarafından barındırılan sürümü kullanma" idi. :-)
Nosredna

7
Tabii ki, ciddi bir web sitesine ev sahipliği yapmak istiyorsanız, dosyalarınızı barındıran başka birine güvenmemenizdi.
Bryan Migliorisi

6
@Bryan Migliorisi, sanırım Twitter sonuçta bu kadar ciddi değil mi? Ancak, Google'ın çöktüğü bir ay önce olduğu gibi Google ile sorun yaşadıklarını itiraf ediyorum.
Ionuț G. Stan

18
Google kullanmanın yararları JS lib hosting için faydalıdır, ancak diğer birkaç konuda tartışılmıştır. Yükleme gecikmeleri hakkında JS geri dönüşüyle ​​ilgili teknik cevaplar arıyordum.
Nosredna

2
@Joe Chung: Sayfa yüklemesini hızlandırarak kullanıcının sisteminde önbelleğe alınması muhtemeldir. Beni bant genişliğinden kurtarıyor. Google'ın CDN'sini kullanır. Etc.
Nosredna

Yanıtlar:


810

Bunu şu şekilde başarabilirsiniz:

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

Bu, sayfanızın içinde olmalı <head>ve <body>hataları önlemek için herhangi bir jQuery hazır olay işleyicisinin içinde olması gerekir (her ne kadar aptal değil!).

İçin bir neden daha değil Google tarafından barındırılan kullanmak jQuery bazı ülkelerde, Google'ın alan adı yasak olmasıdır.


35
Javascript indirmeleri engelleme (senkron) zaten değil mi? Bana öyle geliyor ki çift kopya sorunu bu yüzden sorun olmaz.
Matt Sherman

68
Matt Sherman'ın dediği gibi, Javascript indirmeleri zaten eşzamanlı olmalıdır. Aksi takdirde, sayfa yalnızca yarısı indirilen bir kitaplığa dayanan bir satır içi komut dosyası yürütmeye çalıştıysa veya kitaplık tamamen karşıdan yüklenip yürütülmeden kitaplık uzantısı yürütüldüğünde birçok sorun ortaya çıkar. Yahoo YSlow'un javascript'i sayfaların sonuna yerleştirmeyi önermesinin bir nedeni de budur; böylece diğer sayfa öğelerinin (stiller ve resimler dahil) indirilmesini engellemez. En azından, tarayıcının ardışık olarak gerçekleşmesi için yürütmeyi ertelemesi gerekir.
20'de gapple

42
Doğrulayıcı fanatiğinden küçük düzeltme: JavaScript'te '</' dizesine izin verilmez, çünkü komut dosyası etiketinin sonu olarak yanlış yorumlanabilir (SGML kısa etiket notasyonu). Bunun yerine '<' + '/ script>' yapın. Şerefe,
Boldewyn

8
Bu örnek çalışmaz. 1) Google ajax kitaplığı yoksa, başarısız olmadan önce zaman aşımına uğraması gerekir. Bu biraz zaman alabilir. Bilgisayarımı ağdan ayırma testimde sadece denedi ve denedi ve denedi ve zaman aşımı yapmadı. 2) jQuery tanımlanmadığı için (! JQuery) bir hata verirse, Javascript bununla ne yapacağını bilmez.
RedWolves

32
JQuery'nin yüklenip yüklenmediğini test etmek için, (! Window.jQuery) iyi çalışır ve sonra typeof check kısaltılır.
Jörn Zaefferer

335

Bunu yapmanın en kolay ve en temiz yolu:

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

1
@jpp için değil XHTML 1.0veHTML 4.01
BenjaminRH

5
İnsanlar type="text/javascript"parçaları kaldırmamı istiyorlar , bu yüzden eski tarayıcılar için html yazan insanlar için, şimdi bunu eklemeniz gerekeceğini unutmayın.
BenjaminRH

6
@BenjaminRH: type="text/javascript"Javascript'i varsayılan olarak kullandıkları için eski tarayıcılarda da gereksizdi. Gerçekten eski tarayıcılar bu languageözelliğe baktı ; ancak o zaman bile, özellik eksikse Javascript varsayılan değerdi.
Martijn

1
@Martijn Ama parlak doğrulama rozetini beğendim :)
BenjaminRH

3
@Trojan Tamamen mümkün, sadece çağrıları yığını. Bu noktada yeni bağlantı ana bilgisayarları açtığınızı, bu nedenle HTTP boru hattının muhtemelen daha hızlı olacağını unutmayın. ... <script src="//cdn1.com/jquery.js"></script> <script>window.jQuery || document.write('<script src="//cdn2.com/jquery.js"><\/script>')</script> <script>window.jQuery || document.write('<script src="local/jquery.js"><\/script>')</script>
Tom McKenzie

76

Bu benim için işe yarıyor gibi görünüyor:

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

Çalışma şekli, http://www.google.com/jsapigoogle çağrılması nesneye yüklenen nesneyi kullanmaktır. Bu nesne yoksa, Google'a erişimin başarısız olduğunu varsayıyoruz. Bu durumda, kullanarak yerel bir kopya yüklüyoruz . (Bu durumda kendi sunucumu kullanıyorum, lütfen bunu test etmek için kendi sunucunuzu kullanın).windowdocument.write

Ben de varlığını test window.google.load- Ben de typeofşeyler nesne veya fonksiyonları uygun olduğunu görmek için bir kontrol yapabilir . Ama bence bu hile yapıyor.

İşte sadece yükleme mantığı, çünkü test ettiğim tüm HTML sayfasını yayınladığımdan beri kod vurgulama başarısız oluyor:

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

Söylemeliyim de, bu site ziyaretçileriniz için bir endişe ise Google AJAX Kütüphaneleri API'sı ile uğraşmanız gerektiğinden emin değilim .

Eğlenceli gerçek : Başlangıçta çeşitli sürümlerde bir try..catch bloğu kullanmaya çalıştım ama bu kadar temiz bir kombinasyon bulamadım. Bu fikrin diğer uygulamalarını, sadece bir alıştırma olarak görmek isterim.


1
Bu durumda, aonyx.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js dosyasını Rony'nin önerdiği gibi doğrudan yüklemek yerine, google.load kullanmanın avantajı nedir? Yüklemenin doğrudan kaldırılan kitaplıklarla ilgili sorunları da yakaladığını tahmin ediyorum (Google JQuery 1.3.2 sunmayı bırakırsa). Ayrıca, Rony'nin sürümü, özellikle jsapi önbellekten yüklendiğinde www.google.com/jsapi alındıktan SONRA ağ sorunlarını fark eder? Emin olmak için google.load geri aramasını kullanmak gerekebilir (ya da if (..) içine google.load'u dahil etmek için bir dönüş değeri olabilir).
Arjan

Biri Google.com'un varlığını test ediyorsa, biri ağ araması yapabilir veya biri "gatekeeper" nesnesinin varlığını kontrol edebilir. Yaptığım şey, google nesnesini ve "yükle" işlevini kontrol etmektir. Her ikisi de başarısız olursa, hiçbir google ve yerel sürümüne ihtiyacım var. Rony'nin sürümü aslında www.google.com/jsapi URL'sini tamamen yok sayar, bu yüzden neden getirileceğini belirttiğinizden emin değilim.
artlung

Sonunda, tüm gereken jquery kitaplığı yüklü olmasıdır. Herhangi bir Google kütüphanesi zorunlu değildir. Rony'nin cevabına göre, Google'dan (veya önbellekten) yüklemenin başarılı olup olmadığından emin olunur. Ancak "if (window.google && window.google.load)" için yaptığınız çekte, jquery kitaplığı hala yüklü değil. Jquery kütüphanesinin gerçek yüklemesi doğrulanmamış mı?
Arjan

ah, karışıklığa nasıl sebep olduğumu görüyorum. "Rony'nin sürümü www.google.com/jsapi getirildikten SONRA ağ sorunlarını fark eder" daha iyi okunmalıdır: "Sürümünüz www.google.com/jsapi getirildikten SONRA ağ sorunlarını fark etmiyor".
Arjan

2
Kısa süre önce Google'ı jQuery ana bilgisayarımız olarak kullanmaya başladık; engellenen kullanıcılardan herhangi bir hata raporu alırsak, müşteri kodumuzu yeniden düzenlemek için cevabınızın bir çeşidini kullanacağım. İyi cevap!
Jarrod Dixon

30

Sitenize gömülü modernizr.js varsa, komut dosyalarınızı eşzamansız olarak yüklemek için yerleşik yepnope.js'yi kullanabilirsiniz - diğerleri arasında jQuery (yedekli).

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

Bu, jQuery'yi Google-cdn'den yükler. Daha sonra, jQuery başarıyla yüklendiyse kontrol edilir. Değilse ("hayır"), yerel sürüm yüklenir. Ayrıca kişisel komut dosyalarınız yüklenir - "her ikisi de", yükleme işleminin testin sonucundan bağımsız olarak başlatıldığını belirtir.

Tüm yükleme işlemleri tamamlandığında, 'Uygulamam.init' durumunda bir işlev yürütülür.

Ben şahsen asenkron script yükleme bu şekilde tercih ederim. Ve bir site kurarken modernizr tarafından sağlanan özellik testlerine güvendiğim için, yine de siteye yerleştirilmiştim. Yani aslında ek yük yok.


2
Sorunun noktasını kaçırdığınızı düşünüyorum - moernizr betiğini bir CDN'den nasıl yüklersiniz?
George Filippakos

2
Modernizr'ı bir CDN'den yüklemeyi tavsiye edemem. Modernizr.com'dan en küçük özel yapıyı tercih etmeliyiz.
Emanuel Kluge

2
Yani bu seçenek +16 alır, 500/200 + ile karşılaştırıldığında diğer seçenekler elde edilir. Ama bu kulağa hoş geliyor. Modernizer'e bağlı olduğu için popüler değil mi? Yine de sitemizde Modernizer kullanıyorum, bu diğer cevaplardan daha iyiyse, biri bana haber verebilir mi? JQuery için oldukça yeniyim, bu yüzden açıklama takdir ediliyor.
redfox05

2
Bu, cevap zamanında gerçekten iyi bir seçimdi, ancak 2015 yepnope.jsitibariyle kullanımdan kaldırıldı. bkz. stackoverflow.com/questions/33986561/…
Obmerk Kronen

Modernizr, bu soru gibi problemleri çözmek için yaratıldı. +1
Carlos Quijano

21

Burada bazı harika çözümler var, ancak yerel dosya ile ilgili bir adım daha ileri gitmek istiyorum.

Google'ın başarısız olduğu bir senaryoda, yerel bir kaynak yüklemesi gerekir, ancak sunucudaki fiziksel bir dosya mutlaka en iyi seçenek olmayabilir. Ben şu anda aynı çözümü uyguluyorum çünkü bu getirmek, bir veri kaynağı tarafından oluşturulan yerel bir dosyaya geri dönmek istiyorum.

Bunun nedenlerinden biri, Google'dan yüklediğim şeyin yanı sıra yerel sunucuda sahip olduğum şeyleri takip etmek konusunda biraz aklıma sahip olmak istiyorum. Sürümleri değiştirmek istersem, yerel kopyamı Google'dan yüklemeye çalıştığım şeyle senkronize tutmak istiyorum. Birçok geliştiricinin bulunduğu bir ortamda, en iyi yaklaşımın bu işlemi otomatikleştirmek olduğunu düşünüyorum, böylece tek bir yapılandırma dosyasındaki sürüm numarasını değiştirmek gerekir.

İşte teorik olarak çalışması gereken benim önerilen çözüm:

  • Bir uygulama yapılandırma dosyasında 3 şey depolayacağım: kütüphane için mutlak URL, JavaScript API'sı için URL ve sürüm numarası
  • Kütüphanenin dosya içeriğini alan (URL'yi uygulama yapılandırmasından alan), adı ve sürüm numarasıyla veri kaynağımda saklayan bir sınıf yazın
  • Yerel dosyamı db'den dışarı çeken ve sürüm numarası değişinceye kadar dosyayı önbelleğe alan bir işleyici yazın.
  • Değişirse (uygulama yapılandırmamda), sınıfım dosya içeriğini sürüm numarasına göre çekecek, veri kaynağımda yeni bir kayıt olarak kaydedecek, ardından işleyici devreye girecek ve yeni sürümü sunacak.

Teorik olarak, eğer kodum düzgün yazılmışsa, tek yapmam gereken benim uygulama yapılandırmasında sürüm numarasını değiştirmek sonra viyola! Otomatikleştirilmiş bir yedek çözümünüz var ve sunucunuzda fiziksel dosyaları korumak zorunda değilsiniz.

Herkes ne düşünüyor? Belki bu aşırıya kaçar, ancak AJAX kitaplıklarınızı korumanın zarif bir yöntemi olabilir.

meşe palamudu


Tüm bu işleri sadece jQuery için yapıyorsanız , aşırıya kaçmış olduğunu söyleyebilirim. Ancak, uygulamanızın diğer parçaları için zaten bu bileşenlerden bazılarına sahipseniz (örneğin, bir DB'den komut dosyaları yüklüyorsanız), o zaman oldukça güzel görünüyor.
Michael Haren

1
Tam ve yeni olduğu için +1, ancak yararın dev zamanını ve karmaşıklığını haklı olduğuna ikna olmadım.
Cory House

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

}

Google'ın kopyasını CDN'den eklemeyi denedikten sonra.

HTML5'te typeözelliği ayarlamanıza gerek yoktur .

Ayrıca kullanabilirsiniz...

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

2
+1 daha temiz görünüyor. 'undefined' sonra ery küçük iki kapanış parantez beri temizleyemez üst küçük bir yazım hatası var
naveen

1
İlk seçenek Krom uyarısından kaçınır[Violation] Avoid using document.write().
Bob Stein

İlk seçenek maalesef senkronize olarak yüklenmiyor gibi görünüyor . İkinci seçenek yapar .
Bob Stein

10

Yerel dosyanızı son çare olarak kullanmak isteyebilirsiniz.

Görünüşe göre jQuery'nin kendi CDN'si https'yi desteklemiyor. Eğer öyleyse, önce oradan yüklemek isteyebilirsiniz.

İşte sıra: Google CDN => Microsoft CDN => Yerel kopyanız.

<!-- 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> 

Gerçekten birden fazla yedeklemeye ihtiyaç var mı? her ikisi de çevrimdışı kullanıcı sitenizi görmeden önce bir dakikadan fazla bekleyecek
George Filippakos

1
Bir komut dosyasının yüklenememesi 1 dakika sürmez, yapar.
Edward Olamisan

@ geo1701 ve Edward, Üçüncüye gerçekten gerek yok. Bir geri dönüşün bile henüz güvenilir olduğu kanıtlanmamıştır. Google API bozuksa, ilk denemenin başarısız olacağına dair henüz bir garanti görmedim. Burada belirtildiği gibi bir CDN'nin
hexalys

6

Koşullu olarak en son / eski jQuery sürümünü ve yedeğini yükleyin:

<!--[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]-->

Bu tarayıcılar arası uyumlu değildir.
Josh Habdas

Josh, evet, öyle.
neiker



4

İşte bu konuda harika bir açıklama!

Ayrıca yükleme gecikmeleri ve zaman aşımları uygular!

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


Yalnızca bağlantı yanıtları yararlı değildir ve düşük kalite olarak kabul edilir. Elbette kaynağa atıfta bulunarak ilgili bitleri cevabınıza kopyalamayı düşünün.
random_user_name

@cale_b Şaka mı yapıyorsun? Bu cevap 7 yaşın üzerindedir, bu nedenle böyle bir yorum yapılmamıştır.
Stuart.Sklinar

Evet, bu eski bir cevap. Ancak önerileri geçerli. Sadece başka bir yerde bağlantı olan cevaplar silinmeye adaydır. Diğer okuyucu: meta.stackoverflow.com/q/8259
Rob

Tamamen katılıyorum, önerileri kendim ılımlı yapardım - ama 7 yıl sonra bunu söylemek anlamsız. 7 yıl önce değil, 7 yıl önce ılımlı olmalıydı.
Stuart.Sklinar

1
@ Stuart.Sklinar - Eğer 7 yıl önce görmüş olsaydım, yapardım :) Kendimi burada biraz araştırma yaparak buldum ve bunu ilk kez gördüm. Sizi hayal kırıklığına uğrattığım için üzgünüm - Bence
SO'daki

4

ASP.NET MVC 5 kullanan kişiler için, jquery için CDN'yi etkinleştirmek üzere BundleConfig.cs dosyasına bu kodu ekleyin:

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

GÜNCELLEME:
Bu cevap yanlış çıktı. Gerçek açıklama için lütfen yorumlara bakınız.


Sorunuzun çoğuna cevap verildi, ancak son bölüme gelince:

Her iki kopyanın da gelmesi tehlikesi ne olabilir?

Gerçekten yok. Bant genişliğini boşa harcarsınız, ikinci bir yararsız kopya indirerek milisaniye ekleyebilir, ancak ikisi de gelirse gerçek bir zarar gelmez. Tabii ki, yukarıda belirtilen teknikleri kullanarak bundan kaçınmalısınız.


5
Aslında, bu soruya göre jQuery'nin iki kez yüklenmesi çok fazla soruna neden olabilir .
ShadowCat7

neden kendiniz test etmiyorsunuz ve jquery kütüphanesini iki kez manuel olarak yüklemiyorsunuz. o zaman cevap ortaya çıkacaktır.
luke_mclachlan

Neden bu kadar yanlış? @ ShadowCat7 neden olduğu sorunlar hakkında daha spesifik olabilir misiniz? Bağladığınız soruda açıkça tanımlandığım tek sorun "önceden yüklenmiş tüm eklentileri silmek". Ancak bu, aynı jQuery dosyasını arka arkaya iki kez yüklemek için geçerli değildir, değil mi? Yerel yedeği burada diğer çözümler yüzden dolambaçlı çünkü sormak ve document.write olarak iftiraya edilir kötülük bazı yerlerde .
Bob Stein

2

Zaten yüklü değilse dinamik olarak jQuery yüklemesi gereken bir Gist yaptım ve kaynak başarısız olursa, yedeklere (birçok cevaptan birleştirilmiş olarak) devam eder: https://gist.github.com/tigerhawkvok/9673154

Gist'i güncel tutmayı planladığımı lütfen unutmayın, ancak bu cevabı değil, değerinde!

/* 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

Google Tarafından Barındırılan jQuery

  • Eski tarayıcıları, özellikle IE9'dan önceki IE sürümlerini önemsiyorsanız, bu en yaygın uyumlu jQuery sürümüdür
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  • OldIE'yi umursamıyorsanız, bu daha küçük ve daha hızlıdır:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

Yedekleme / Yedekleme Planı!

  • Her iki durumda da, Google CDN'nin başarısız olması (olası olmaması) veya kullanıcılarınızın sitenize İran veya bazen Çin gibi eriştiği (biraz daha muhtemel) bir konumda engellenmesi durumunda yerel bir yedek kullanmalısınız.
<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>

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


Güvenli olmayan protokoller üzerine komut dosyaları yüklendiğinde bir XSS saldırı vektörü açılır.
Josh Habdas

2

Dize son <to \ x3C kaçması gerektiğini düşünüyorum. Tarayıcı gördüğünde, bunun komut dosyası bloğunun sonu olduğunu düşünür (HTML ayrıştırıcısı JavaScript hakkında hiçbir fikre sahip olmadığından, yalnızca bir dizede görünen bir şey ile gerçekte komut dosyasını sonlandırmak anlamına gelen bir şey arasında ayrım yapamaz. elemanı) sağlanabilir. Dolayısıyla, tam anlamıyla bir HTML sayfasının içindeki JavaScript'te görünmek (en iyi durumda) hatalara neden olur ve (en kötü durumda) büyük bir güvenlik açığı olur.

<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
if (typeof jQuery == 'undefined')) { ...

Veya

if(!window.jQuery){

Cdn sürümü yüklenmediyse çalışmaz, çünkü tarayıcı bu koşul boyunca çalışır ve bu sırada hala jQuery gerektiren javascripts'i indirir ve hata döndürür. Çözüm, bu koşulda komut dosyaları yüklemekti.

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

Google Chrome'da önbellek testlerinde bir sorun buldum. Bu nedenle yerel testler için src'yi diğer bölümlerde s.src = 'my_javascripts.js' + '?' + Math.floor (Math.random () * 10001);
Mirek Komárek

CDn sürümü yüklenmediyse Alex'in cevabı çalışmaz, çünkü tarayıcı bu koşuldan geçecek ve jquery gerektiren javascripts'i indirirken hata veriyor -> İndirilen JavaScript dosyaları bir sonraki kod parçasının çalıştırılmasını engelleyecek yani bu bir sorun değil .
alex

2

Neredeyse tüm halka açık CDN'ler oldukça güvenilirdir. Ancak, engellenen google alan adı konusunda endişeleriniz varsa, alternatif bir jQuery CDN'ye geri dönebilirsiniz . Bununla birlikte, böyle bir durumda, başarısız istekleri ve bekleme süresini önlemek için ters yönde yapmayı ve tercih ettiğiniz seçenek olarak başka bir CDN kullanmayı ve Google CDN'ye geri dönmeyi tercih edebilirsiniz:

<script src="https://pagecdn.io/lib/jquery/3.2.1/jquery.min.js"></script>
<script>
   window.jQuery || document.write('<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"><\/script>');
</script>

1

ASP.NET'te Razor sözdizimini kullanan bu kod, yedek destek sağlar ve sanal bir kökle çalışır:

@{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>

Veya bir yardımcı yapın ( yardımcıya genel bakış ):

@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>")
}

ve şu şekilde kullanın:

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

Ben Razor hakkında kalp asla ettik, ama buna kodu yapar haricinde bir Gizleyiciyi benziyor uzun ziyade (bu sürece iki kat daha kısa bu .
maaartinus

@maaartinus: Bu bir elma-elma karşılaştırması değil. BenjaminRH'nin bahsettiğiniz yanıtı, CDN tarafından barındırılan tek bir komut dosyası içindir. CdnScriptYardımcı ile komut dosyası başına yalnızca bir satır kod gerekir . Ne kadar çok komut dosyanız varsa, getiri o kadar büyük olur.
Edward Brey

Tabii ... sadece bir ranttı. Ancak, sanırım bu en uygun yol değil. Bir şey başarısız olursa, CDN'yi tamamen görmezden gelir ve tüm komut dosyaları için yedeklemeye geçerdim. Yüklemenin tam olarak nasıl çalıştığını bilmediğim için bunun yapılabilir olup olmadığından emin değilim.
maaartinus

@maaartinus: Her CDN komut dosyası yükü bağımsız olarak başarısız olabileceğinden, her yükü ayrı ayrı kontrol etmeniz gerekir. Tek bir CDN kontrolünün güvenilir bir yöntemi yoktur, ardından CDN'den yerel olarak tüm komut dosyalarını yükler.
Edward Brey

Beni endişelendiren durum, birçok yük için bekleme süresine yol açan CDN sitesinin başarısız olmasıdır. Ben de böyle bir şeye sahip olmak istiyorum try { for (Script s : ...) cdnLoad(s); } catch (...) { for (Script s : ...) ownLoad(s); }. Bunu bir demet ifs'ye çevirmek kabus olabilir.
maaartinus

1

document.write("<script></script>")JQuery geri çekilmesi için yazma daha kolay görünse de, Chrome bu durumda doğrulama hatası verir. Bu yüzden "script" kelimesini kırmayı tercih ederim. Böylece yukarıdaki gibi daha güvenli hale gelir.

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

Uzun vadeli sorunlar için JQuery yedeklerini günlüğe kaydetmek daha iyi olur. Yukarıdaki kodda, ilk CDN yoksa JQuery başka bir CDN'den yüklenir. Ancak bu hatalı CDN'yi bilmek ve kalıcı olarak kaldırmak isteyebilirsiniz. (Bu durum çok istisnai bir durumdur) Ayrıca yedek sorunları kaydetmek daha iyidir. Böylece AJAX ile hatalı vakalar gönderebilirsiniz. JQuery tanımlanmadığı için AJAX isteği için vanilya javascript'i kullanmalısınız.

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


0

Henüz başka çare cümledeki o ajax.googleapis.com ile 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);
  • Bir jQuery sürümüne dizede belirterek yapıştırabilirsiniz
  • HTML snip'leriyle çalışmayan Varlık Yönetimi için mükemmel
  • Vahşi doğada test edildi - Çin'den gelen kullanıcılar için mükemmel çalışıyor

Aşağıdaki ifadeyi açıklayabilir misiniz: "jQuery sürümünü önemsemeniz gerekmez"?
Josh Habdas

Sürüm, URL'nin bu yaklaşımdan etkilenmeyecek bir parçası ... jquery / 3.xx / jquery.min.js
redaxmedia

1
JQuery sürüm 4'e geri döndüğünde ve geriye doğru uyumsuz değişiklikler getirdiğinde bunun kırılma potansiyeli var mı?
Josh Habdas

-1 çünkü jQuery, sürüm belirtilmedikçe komut dosyalarınızın henüz desteklemeyeceği sonlandırma değişiklikleri yaparsa bu durum bozulmaya neden olur.
Lookaji

@lookaji Sanırım yedeklemeyi anlamıyorsun. Barındırıldığı etki alanının yerini alır ve dosya adına / sürüme hiç dokunmaz.
redaxmedia

0

Aşağıdaki gibi bir kod kullanabilirsiniz:

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

Ancak , komut dosyalarınız için birkaç olası yedek oluşturmak ve yükleme işlemini optimize etmek için kullanabileceğiniz kütüphaneler de vardır :

  • basket.js
  • RequireJS
  • yepnope

Örnekler:

basket.js Bence şimdilik en iyi varyant. Komut dosyanızı localStorage'da önbelleğe alır, bu da sonraki yüklemeleri hızlandırır. En basit çağrı:

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

Bu bir söz döndürür ve bir sonraki hata durumunda çağrı yapabilir veya başarıya bağımlılıklar yükleyebilirsiniz:

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');
    }
  }
}]);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.