如何在CDN被阻止/不可用的情况下加载本地脚本文件作为后备?

时间:2011-03-10 09:52:02

标签: javascript cdn fallback

11 个答案:

答案 0 :(得分:224)

要确认加载了cdn脚本,您可以检查此脚本定义的任何变量/函数是否存在,如果未定义 - 则cdn失败,您需要加载本地脚本副本。

基于这个原则是基于这样的解决方案:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/libs/jquery-1.5.1.min.js">\x3C/script>')</script>

(如果没有window.jQuery属性定义的cdn脚本没有加载)。

您可以使用此方法构建自己的解决方案。例如,jquery工具提示插件会创建$.tooltip()函数,因此我们可以使用以下代码进行检查:

<script>
    if (typeof $.tooltip === 'undefined') {
        document.write('<script src="js/libs/jquery.tooltip.min.js">\x3C/script>');
    }
</script>

答案 1 :(得分:16)

我会查看像yepnopejs

这样的插件
yepnope([{
  load: 'http:/­/ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js',
  complete: function () {
    if (!window.jQuery) {
      yepnope('local/jquery.min.js');
    }
  }
}]);

获取要检查的对象数组,请查看site

上的文档

答案 2 :(得分:6)

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.4.2.js"%3E%3C/script%3E'))</script>

取自HTML5 Boilerplate

答案 3 :(得分:4)

我使用http://fallback.io/

  fallback.load({
        // Include your stylesheets, this can be an array of stylesheets or a string!
        page_css: 'index.css',

        // JavaScript library. THE KEY MUST BE THE LIBARIES WINDOW VARIABLE!
        JSON: '//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.min.js',

        // Here goes a failover example. The first will fail, therefore Fallback JS will load the second!
        jQuery: [
            '//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.FAIL_ON_PURPOSE.min.js',
            '//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js',
            '//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js'
        ],   .......

答案 4 :(得分:3)

首先 - 你不应该以不同的顺序包括它们吗?

这样的事情应该有效:

<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js"></script>
<script>jQuery.fn.validate || document.write('<script src="js/jquery.validate.min.js">\x3C/script><script src="js/jquery.validate.unobtrusive.min.js">\x3C/script>'</script>

我在这里做的只是检查是否已加载第一个插件(jQ validate)。通过检查jQuery.fn对象上的静态validate函数。我无法以相同的方式检查第二个脚本,因为它不会在任何地方添加任何内容,只是代理现有方法,因此更容易假设如果第一个脚本有效,第二个脚本也可以工作 - 毕竟,它们是由相同的CDN。

答案 5 :(得分:2)

您需要知道如何确保成功加载lib。例如:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js"></script>
<script>window.jQuery || document.write('<script src="js/jquery.min.js">\x3C/script>'</script>

因此,这可以从谷歌CDN加载jQuery(1.5.1)。由于<script>标记会阻止整体渲染和放大执行过程(如果没有明确说明不同),我们可以在此之后检查jQuery对象是否在window内找到。如果没有,只需通过在文档中写入另一个<script>标记,引用本地副本来回退。

答案 6 :(得分:2)

以下解决方案通过了HTML5,XHTML 1.0 Transitional和其他HTML风格的验证。在每个外部JQuery调用之后放置以下内容。请务必将jquery.min.js替换为JQuery脚本本地副本的路径。

<script type="application/javascript">window.jQuery || 
document.write(unescape('%3Cscript src="jquery.min.js"%3E%3C/script%3E'))</script>

如果您不使用unescape,则在使用http://validator.w3.org进行验证时会出错,因为属性规范列表中不允许使用“%”。

与旧版HTML一起使用时,HTML5 Boilerplate示例也存在验证错误:

  1. 未指定必需属性“type”
  2. 字符“&amp;”是分隔符的第一个字符,但是作为数据出现
  3. 如果您只为HTML5和未来的HTML风格开发,那么您可以使用HTML5 Boilerplate解决方案,但是因为您可能会发现自己将部分代码插入到旧版HTML中,所以使用这种单一尺寸可以安全地使用它 - 所有方法。

    您需要为每个外部托管的脚本指定不同的功能。例如,JQuery Tooltip插件创建了$ .tooltip()函数,因此您可以使用以下命令进行检查:

    <script type="application/javascript">typeof ($.tooltip()) !== 'undefined' || 
    document.write(unescape('%3Cscript src="jquery.tooltip.min.js"%3E%3C/script%3E'))</script>
    

答案 7 :(得分:1)

我在jquery ui - how to use google CDN

回答了类似的问题

您可以使用

拨打电话
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css" type="text/css" media="all" /> 
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.5.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js" type="text/javascript"></script>

您还可以通过更改主题名称链接到其他Ui主题。在这种情况下,将名称库更改为任何其他主题名称/base/jquery-ui.css到任何其他主题。

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css" type="text/css" media="all" />

查看jQuery UI博客,获取所有CDN链接http://blog.jqueryui.com/

的链接

如果您想要在Google失败的情况下还原到您的主机,您可以

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript">
if (typeof jQuery == 'undefined')
{
    document.write(unescape("%3Cscript src='/jquery.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>

答案 8 :(得分:1)

如果相关的CDN真的被过滤掉了,我认为任何解决方案都不会毫无痛苦。 (例如iptables / drop,配置错误的路由器。) 如果你不相信他们在本地使用所有东西......你可以在异国情调的网络上给用户留下一些惊喜/电话。

答案 9 :(得分:0)

<script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min.js" type="text/javascript"></script>   
<script type="text/javascript">
if(typeof jQval == 'undefined')
{
    document.write(unescape("%3Cscript src='/Scripts/jquery.validate.unobtrusive.min.js' type='text/javascript'%3E%3C/script%3E"));
    document.write(unescape("%3Cscript src='/Scripts/jquery.validate.min.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>

取自this article

答案 10 :(得分:0)

最好使用您自己的Javascript代码加载所有此脚本。

首先尝试通过在DOM中插入新的SCRIPT元素来加载CDN文件。然后通过查找它定义的对象来检查它是否已加载。如果没有出现该对象,则插入另一个SCRIPT元素以加载本地副本。可能最好清理DOM并删除无法加载的SCRIPT。

不要忘记考虑时间问题,即负载不是即时的。