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

我正在使用以下的JavaScript的CDN:

  • https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
  • https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js
  • ajax/mvc/3.0/jquery.validate.unobtrusive.min.js
  • ajax/jquery.validate/1.7/jquery.validate.min.js

对于每一个,我怎么能恢复使用本地副本的情况下,它可能被阻止/不可用?

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

在这个原则上是基于这样的解决scheme:

<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脚本没有加载)。

你可以使用这种方法build立自己的解决scheme。 例如,jQuery的工具提示插件创build$.tooltip()函数,所以我们可以用这样的代码来检查它:

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

我会看看像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'); } } }]); 

拿一些对象来检查,检查网站上的文档

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

我使用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' ], ....... 

第一件事 – 你不应该以不同的顺序包含它们吗?

像这样的东西应该工作:

 <script src="ajax/jquery.validate/1.7/jquery.validate.min.js"></script> <script src="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> 

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

你需要知道,如何确保一个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>标签确实会阻塞整个渲染和执行过程(如果没有明确地告诉它们不同),那么如果在window内find了jQuery对象,我们可以立即检查。 如果不是这样,只需通过在文档中写入另一个<script>标记来引用本地副本即可。

以下解决scheme通过HTML5,XHTML 1.0 Transitional和其他HTML风格的validation。 在每个外部JQuery调用之后放置以下内容。 确保将jquery.min.jsreplace为本地JQuery脚本副本的path。

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

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

与旧版HTML一起使用时,HTML5 Boilerplate示例也具有validation错误:

  1. 未指定必需属性“type”
  2. 字符“&”是分隔符的第一个字符,但是作为数据出现

如果您只为HTML5和将来的HTML风格开发,那么您可以使用HTML5 Boilerplate解决scheme,但由于您可能会发现自己的代码部分插入到传统HTML中,因此可以采用这种一刀切式的方法。

您需要为每个外部托pipe的脚本指定一个不同的函数。 例如,JQuery Tooltip插件创build$ .tooltip()函数,所以你可以用下面的方法检查它:

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

我回答了类似的问题在jQuery的UI – 如何使用谷歌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博客链接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> 
 <script src="ajax/mvc/3.0/jquery.validate.unobtrusive.min.js" type="text/javascript"></script> <script src="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> 

从这篇文章采取

最好用你自己的Javascript代码来完成所有的脚本加载。

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

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

如果相关的CDN真的被过滤掉了,我不认为任何解决scheme都是无痛的。 (比如iptables / drop,错误configuration的路由器)。如果你不相信他们在本地使用所有的东西,那么你可以在异国情调的networking上为用户节省一些惊喜/电话。

Interesting Posts