使用Google託管的jQuery的最佳方式,但是回到Google上的託管庫失敗jquery


Answers

最簡單和最乾淨的方式做到這一點:

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

嘗試在Google (或其他Google託管的庫)中加載託管的jQuery是一個好辦法,但如果Google嘗試失敗,則加載我的jQuery副本?

我不是說Google是片狀的。 有些情況下,Google副本被封鎖(顯然在伊朗)。

我會設置一個計時器並檢查jQuery對象嗎?

這兩個副本的危險是什麼?

沒有真正尋找“只使用Google”或“只使用自己的”的答案。 我理解這些論點。 我也明白,用戶可能會緩存Google版本。 我正在考慮一般雲的回退。

編輯:此部分添加...

由於Google建議使用google.load加載ajax庫,並且在完成後執行回調,我想知道這是否是序列化此問題的關鍵。

我知道這聽起來有點瘋狂。 我只是想知道是否可以以可靠的方式完成。

更新:jQuery現在託管在微軟的CDN上。

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




如果您的網站上嵌入了modernizr.js,則可以使用內置的yepnope.js異步加載腳本,其中包括jquery(帶回退)。

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

這會從google-cdn裝載jquery。 之後它被檢查,如果jquery成功加載。 如果沒有(“不”),則加載本地版本。 您的個人腳本也會被加載 - “both”表示負載過程與測試結果無關。

當所有加載進程完成時,執行一個功能,在“MyApp.init”的情況下。

我個人喜歡這種異步腳本加載的方式。 而且,當我依靠現代化在建立站點時提供的功能測試,我也將其嵌入到站點上。 所以實際上沒有開銷。




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

}

嘗試從CDN中包含Google的副本之後。

在HTML5中,您不需要設置type屬性。

你也可以使用...

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



有條件地加載最新/傳統的jQuery版本和後備版本:

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






對於使用ASP.NET MVC 5的人員,將此代碼添加到您的BundleConfig.cs中以啟用用於jquery的CDN:

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



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

要么

if(!window.jQuery){

如果cdn版本沒有加載,將不會工作,因為瀏覽器將運行這種情況,並且仍然下載剩下的需要jquery的JavaScript,並返回錯誤。 解決方案是通過這種情況加載腳本。

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



我認為應該在字符串中逃避最後一個<to \ x3C。 當瀏覽器看到它時,它認為這是腳本塊的結束(因為HTML解析器不了解JavaScript,它不能區分剛剛出現在字符串中的東西,而是實際上旨在結束腳本的東西元件)。 因此,在HTML頁面內的JavaScript中(在最好的情況下)會出現錯誤,並且(在最壞的情況下)是一個巨大的安全漏洞。

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



我做了一個Gist,應該動態加載jQuery,如果它還沒有加載,如果源碼失敗,它會繼續回退(從許多答案拼接在一起): https : //gist.github.com/tigerhawkvok/9673154

請注意,我計劃保持Gist更新,但不是這個答案,為什麼值得!

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