什么是一个好方法来尝试加载托管的jQuery在谷歌(或其他谷歌托管库),但加载我的jQuery副本,如果谷歌尝试失败?

我不是说谷歌很古怪。在某些情况下,谷歌副本会被屏蔽(例如,显然在伊朗)。

我是否会设置一个计时器并检查jQuery对象?

两份拷贝都通过的危险是什么?

并不是真的在寻找像“只用谷歌”或“只用你自己的”这样的答案。我理解这些论点。我还知道用户可能缓存了谷歌版本。我在考虑云计算的后备方案。


编辑:这部分增加了…

因为谷歌建议使用谷歌。加载加载ajax库,它执行回调时,我想知道这是否是序列化这个问题的关键。

我知道这听起来有点疯狂。我只是想弄清楚它是否能以一种可靠的方式完成。


更新:jQuery现在托管在微软的CDN上。

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


当前回答

还有另一个替代ajax.googleapis.com与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);

你可以通过在字符串中指定一个jQuery版本 完美的资产管理,不与HTML剪辑工作 在野外测试-工作完美的用户从中国

其他回答

我做了一个Gist,如果还没有加载jQuery,它应该动态加载,如果源代码失败,它将继续执行回退(从许多答案拼接在一起):https://gist.github.com/tigerhawkvok/9673154

请注意,我计划保持更新主旨,但不是这个答案,因为它是值得的!

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

你应该永远不需要使用个人副本。这是我的全套皮带和牙套脚本。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <title>jQuery</title>
        <!-- EMBED JQUERY USING GOOGLE APIs -->
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

        <!-- IF THAT FAILS EMBED JQUERY USING CLOUDFLARE CDN -->
        <script type="text/javascript">
            window.jQuery || document.write('<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"><\/script>');
        </script>

        <!-- IF THAT FAILS ************* HOW??? *********** EMBED JQUERY FROM MICROSOFT -->
        <script type="text/javascript">
            window.jQuery || document.write('<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.6.0.min.js"><\/script>');
        </script>

        <!-- IF THAT FAILS ************* WOW!!! *********** EMBED JQUERY FROM JQUERY.COM -->
        <script type="text/javascript">
            window.jQuery || document.write('<script src="https://code.jquery.com/jquery-3.6.0.min.js"><\/script>');
        </script>

        <!-- IF THAT FAILS ************* LET'S STOP!!! *********** EMBED JQUERY FROM PERSONAL COPY -->
        <script type="text/javascript">
            window.jQuery || document.write('<script src="jquery.min.js"><\/script>');
        </script>
    </head>
    <body>


    </body>
</html>

这里有一些很好的解决方案,但我想在本地文件方面更进一步。

在谷歌确实失败的情况下,它应该加载一个本地源,但服务器上的物理文件不一定是最佳选择。之所以提出这一点,是因为我目前正在实现相同的解决方案,只是希望返回到由数据源生成的本地文件。

我这样做的原因是,当涉及到跟踪我从谷歌加载的内容与我在本地服务器上的内容时,我想有一些想法。如果我想要更改版本,我将希望保持我的本地副本与我试图从谷歌加载的内容同步。在有许多开发人员的环境中,我认为最好的方法是自动化这个过程,这样所有人所要做的就是更改配置文件中的版本号。

以下是我提出的理论上可行的解决方案:

In an application configuration file, I'll store 3 things: absolute URL for the library, the URL for the JavaScript API, and the version number Write a class which gets the file contents of the library itself (gets the URL from app config), stores it in my datasource with the name and version number Write a handler which pulls my local file out of the db and caches the file until the version number changes. If it does change (in my app config), my class will pull the file contents based on the version number, save it as a new record in my datasource, then the handler will kick in and serve up the new version.

理论上,如果我的代码写得正确,我所需要做的就是改变我的应用程序配置中的版本号,然后viola!你有一个自动的备用解决方案,你不必在服务器上维护物理文件。

大家怎么想?也许这有点过分了,但这可能是维护AJAX库的一种优雅方法。

橡子

这似乎对我很管用:

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

它的工作方式是使用调用http://www.google.com/jsapi加载到窗口对象的谷歌对象。如果该对象不存在,则假设对谷歌的访问失败。如果是这种情况,我们使用document.write加载一个本地副本。(在这种情况下,我使用自己的服务器,请使用自己的服务器进行测试)。

我还测试了window.google.load的存在——我还可以做一个typeof检查,看看这些东西是否是适当的对象或函数。但我觉得这个很管用。

这里只是加载逻辑,因为代码高亮显示似乎失败了,因为我张贴了整个HTML页面,我正在测试:

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

虽然我必须说,我不确定如果这是您的网站访问者的担忧,您应该摆弄谷歌AJAX Libraries API在所有。

有趣的事实:我最初尝试在各种版本中使用try. catch块,但找不到像这样干净的组合。我很有兴趣看到这个想法的其他实现,纯粹作为一个练习。

步骤1:jQuery加载失败?(查看jQuery变量)

如何在JavaScript中检查一个未定义的变量

步骤2:动态导入(备份)javascript文件

如何在另一个JavaScript文件中包含一个JavaScript文件?