Javascript 在 CDN 被阻止/不可用的情况下,如何加载本地脚本文件作为后备?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5257923/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to load local script files as fallback in cases where CDN are blocked/unavailable?
提问by raklos
I'm using a CDN for the following javascript:
我正在为以下 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
- 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
For each one, how can I revert to using local copy in the instance where it may be blocked/unavailable?
对于每一个,我如何在可能被阻止/不可用的实例中恢复使用本地副本?
回答by Dmitry Evseev
To confirm that cdn script loaded you can check for existence any variable/function this script defines, if it is undefined - then cdn failed and you need to load local script copy.
要确认加载了 cdn 脚本,您可以检查此脚本定义的任何变量/函数是否存在,如果未定义 - 则 cdn 失败,您需要加载本地脚本副本。
On this principle are based solutions like that:
基于此原则,基于以下解决方案:
<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>
(if there is no window.jQuery property defined cdn script didn't loaded).
(如果没有 window.jQuery 属性定义的 cdn 脚本没有加载)。
You may build your own solutions using this method. For instance, jquery tooltip plugin creates $.tooltip()
function so we can check it with code like this:
您可以使用此方法构建自己的解决方案。例如,jquery tooltip 插件创建了$.tooltip()
函数,所以我们可以用这样的代码检查它:
<script>
if (typeof $.tooltip === 'undefined') {
document.write('<script src="js/libs/jquery.tooltip.min.js">\x3C/script>');
}
</script>
回答by Eivind
I would have looked into a plugin like yepnopejs
我会研究像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');
}
}
}]);
Takes an array of object to check for, check the documentation at the site
获取要检查的对象数组,请查看站点上的文档
回答by EMMERICH
<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>
Taken from HTML5 Boilerplate.
取自 HTML5 Boilerplate。
回答by wildcard
first thing - shouldn't you include them in different order?
第一件事 - 你不应该以不同的顺序包含它们吗?
something like this should work:
这样的事情应该工作:
<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>
what I'm doing here is simply checking if the first plugin (jQ validate) has been loaded. by checking for a static validate
function on jQuery.fn object. I can't check the second script same way, because it's not adding anything anywhere, just proxying existing methods, so it's easier to assume that if the first one works, the second one will work too - after all, they are provided by the same CDN.
我在这里所做的只是检查是否已加载第一个插件(jQ 验证)。通过检查validate
jQuery.fn 对象上的静态函数。我不能用同样的方式检查第二个脚本,因为它没有在任何地方添加任何东西,只是代理现有的方法,所以更容易假设如果第一个有效,第二个也将有效 - 毕竟,它们是由同一个 CDN。
回答by Maxim
I use 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' ], .......
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' ], .......
回答by Loren
The following solution passes validation for both HTML5, XHTML 1.0 Transitional and other HTML flavors. Place the following after each of your external JQuery call. Be sure to replace jquery.min.js with the path to your local copy of the JQuery script.
以下解决方案通过了 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>
If you don't use unescape, you'll have errors when validating with http://validator.w3.orgsince "%" is not allowed in an attribute specification list.
如果不使用 unescape,则在使用http://validator.w3.org进行验证时会出错,因为属性规范列表中不允许使用“%”。
The HTML5 Boilerplate example also has validation errors when used with older HTML:
HTML5 Boilerplate 示例在与旧 HTML 一起使用时也有验证错误:
- required attribute "type" not specified
- character "&" is the first character of a delimiter but occurred as data
- 未指定必需的属性“类型”
- 字符“&”是分隔符的第一个字符,但作为数据出现
You'll be fine with the HTML5 Boilerplate solution if you are developing only for HTML5 and future HTML flavors, but since you may find yourself inserting portions of your code into legacy HTML, play it safe with this one-size-fits-all approach.
如果您仅针对 HTML5 和未来的 HTML 风格进行开发,那么您可以使用 HTML5 Boilerplate 解决方案,但由于您可能会发现自己将部分代码插入到旧版 HTML 中,因此请使用这种一刀切的方法来确保安全.
You'll need to specify a different function for each externally hosted script. For instance, the JQuery Tooltip plugin creates the $.tooltip() function, so you can check it with the following:
您需要为每个外部托管的脚本指定不同的函数。例如,JQuery Tooltip 插件创建了 $.tooltip() 函数,因此您可以使用以下内容进行检查:
<script type="application/javascript">typeof ($.tooltip()) !== 'undefined' ||
document.write(unescape('%3Cscript src="jquery.tooltip.min.js"%3E%3C/script%3E'))</script>
回答by jAndy
You need to know, how you can make sure that a lib was loaded successfully. For instance:
您需要知道如何确保成功加载了一个库。例如:
<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>
So this trys to load jQuery (1.5.1) from the google CDN. Since <script>
tags do block the overall render & execution process (if not explicitly told different), we can check right after that if the jQuery
object is found within window
. If not, just fallback by writing another <script>
tag into the document, referencing a local copy.
所以这会尝试从谷歌 CDN 加载 jQuery (1.5.1)。由于<script>
标签确实会阻止整个渲染和执行过程(如果没有明确告知不同),我们可以在此之后立即检查jQuery
对象是否在window
. 如果没有,只需通过<script>
在文档中写入另一个标签来回退,引用本地副本。
回答by Hussein
I answered a similar questions at jquery ui - how to use google CDN
我在jquery ui - how to use google CDN回答了一个类似的问题
You can make the call using
您可以使用
<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>
You can also link to other Ui themes by changes the name of the theme. In This case change the name base to any other theme name /base/jquery-ui.css
to any other theme.
您还可以通过更改主题名称链接到其他 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" />
Check out the jQuery UI Blog for a link of all CDN links http://blog.jqueryui.com/
查看 jQuery UI 博客以获取所有 CDN 链接的链接http://blog.jqueryui.com/
If you want to revert back to your host in case Google failed, you can do
如果你想在谷歌失败的情况下恢复到你的主机,你可以这样做
<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>
回答by Lajos Veres
I don't think any of the solutions could be painless if the related CDN is really filtered out. (like for example iptables/drop, misconfigured routers.) If you don't trust them use everything locally... And you spare yourself a few surprises/calls from users on exotic network.
如果相关的 CDN 真的被过滤掉,我认为任何解决方案都不会是无痛的。(例如 iptables/drop,错误配置的路由器。)如果您不信任它们,请在本地使用所有内容……并且您可以避免来自异国网络上的用户的一些惊喜/电话。
回答by Michael Dillon
Best to do all this script loading with your own Javascript code.
最好使用您自己的 Javascript 代码加载所有这些脚本。
First try to load the CDN file by inserting a new SCRIPT element into the DOM. Then check that it has loaded by looking for an object that it defines. If the object does not appear, then insert another SCRIPT element to load the local copy. Probably best to clean up the DOM and remove SCRIPTs which failed to load as well.
首先尝试通过将新的 SCRIPT 元素插入 DOM 来加载 CDN 文件。然后通过查找它定义的对象来检查它是否已加载。如果对象没有出现,则插入另一个 SCRIPT 元素以加载本地副本。可能最好清理 DOM 并删除也无法加载的 SCRIPT。
Don't forget to account for timing issues, i.e. load is not instant.
不要忘记考虑时间问题,即负载不是即时的。