在 CDN 被阻止/不可用的情况下,如何加载本地脚本文件作为后备? [复制]
Posted
技术标签:
【中文标题】在 CDN 被阻止/不可用的情况下,如何加载本地脚本文件作为后备? [复制]【英文标题】:How to load local script files as fallback in cases where CDN are blocked/unavailable? [duplicate] 【发布时间】:2011-07-12 14:10:15 【问题描述】:我正在为以下 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 http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min.js http://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min.js对于每一个,我如何在可能被阻止/不可用的情况下恢复使用本地副本?
【问题讨论】:
这里有一个解决方案:***.com/questions/2607425/… 是的,我看到了类似的东西,并且想知道如何为验证和不引人注目的东西做这件事。 可能重复,但这个问题更容易找到 这是你的答案:***.com/a/56712767/369005 【参考方案1】:要确认已加载 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 插件创建了$.tooltip()
函数,因此我们可以使用如下代码检查它:
<script>
if (typeof $.tooltip === 'undefined')
document.write('<script src="js/libs/jquery.tooltip.min.js">\x3C/script>');
</script>
【讨论】:
对于任何想知道作者为什么使用\x3c
的人,这是因为否则</script>
会过早结束脚本。
<\/script>
也可以正常工作。
为什么不if ($.tooltip === undefined)
?
也是有效的,有很多方法可以检查是否存在。我喜欢typeof
检查他们是bulletproof
不推荐使用document.write
。 document.write
脚本的网络请求可能被浏览器阻止:developers.google.com/web/updates/2016/08/… & chromestatus.com/feature/5718547946799104【参考方案2】:
我会研究像 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的文档
【讨论】:
不错的解决方案。从文档看来,您仍然需要测试一个对象:yepnope([ test : /* boolean(ish), ...
。所以看来@raklos 你需要找出一个要测试的对象。
但是如果load
失败,complete
event 会被触发吗?看起来很尴尬:-)
@Capsule - 很好的问题。从文档看来,您可以使用在加载或超时时触发的callback: function (url, result, key) ...
。可以覆盖默认超时。我不能说我已经尝试过了,但看起来这可能值得尴尬;)
在加载/未加载所有文件之后,无论成功或失败,都会触发。加载(或不加载)单个文件后触发回调。
2015 注意:yepnope 已弃用 :(【参考方案3】:
<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。
【讨论】:
【参考方案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' ], .......
【讨论】:
【参考方案5】:第一件事 - 你不应该以不同的顺序包含它们吗?
这样的事情应该可以工作:
<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。
【讨论】:
您可以使用“window.jQuery.validator.unobtrusive”测试不显眼。我在这里找到了测试:house9.blogspot.com/2011/03/…【参考方案6】:您需要知道如何确保成功加载库。例如:
<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>
所以这会尝试从 google CDN 加载 jQuery (1.5.1)。由于<script>
标签确实阻塞了整个渲染和执行过程(如果没有明确告知不同),我们可以在此之后检查jQuery
对象是否在window
中找到。如果没有,只需在文档中写入另一个 <script>
标记,引用本地副本。
【讨论】:
我如何为验证和不显眼的人做这件事?【参考方案7】:以下解决方案通过了 HTML5、XHTML 1.0 过渡和其他 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 进行验证时会出错,因为属性规范列表中不允许使用“%”。
HTML5 Boilerplate 示例在与旧版 HTML 一起使用时也会出现验证错误:
-
未指定必需的属性“类型”
字符“&”是分隔符的第一个字符,但作为数据出现
如果您只为 HTML5 和未来的 HTML 风格进行开发,您可以使用 HTML5 Boilerplate 解决方案,但由于您可能会发现自己将部分代码插入到旧版 HTML 中,因此请放心使用这种万能的解决方案-all 方法。
您需要为每个外部托管脚本指定不同的函数。例如,JQuery Tooltip 插件创建了 $.tooltip() 函数,因此您可以通过以下方式对其进行检查:
<script type="application/javascript">typeof ($.tooltip()) !== 'undefined' ||
document.write(unescape('%3Cscript src="jquery.tooltip.min.js"%3E%3C/script%3E'))</script>
【讨论】:
【参考方案8】:我在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>
【讨论】:
不过,这不会后备加载 CSS...【参考方案9】:<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】:最好使用您自己的 Javascript 代码加载所有这些脚本。
首先尝试通过将新的 SCRIPT 元素插入 DOM 来加载 CDN 文件。然后通过查找它定义的对象来检查它是否已加载。如果对象没有出现,则插入另一个 SCRIPT 元素以加载本地副本。可能最好清理 DOM 并删除也无法加载的 SCRIPT。
不要忘记考虑时间问题,即加载不是即时的。
【讨论】:
以上是关于在 CDN 被阻止/不可用的情况下,如何加载本地脚本文件作为后备? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何在不刷新页面的情况下检测第三方 cookie 被阻止; [?]
从 Azure CDN 请求的字体文件被 CORS 策略阻止
在不重新加载整个表格视图的情况下更改 UITableView 的部分页眉/页脚标题