Best way to use Google's hosted jQuery, but fall back to my hosted library on Google fail
在Google(或其他Google托管的libs)上尝试加载托管的jquery,但如果Google尝试失败,那么加载我的jquery副本有什么好方法?
我不是说谷歌很脆弱。有些情况下谷歌的拷贝会被屏蔽(例如在伊朗)。
我可以设置一个计时器并检查jquery对象吗?
两份复印件都会有什么危险?
不是真的在寻找"只使用谷歌一号"或"只使用你自己的"这样的答案,我理解这些论点。我还了解到用户可能缓存了Google版本。我在考虑云计算的一般回退。
编辑:此部件已添加…
因为google建议使用google.load来加载Ajax库,并且在完成后执行回调,所以我想知道这是否是序列化这个问题的关键。
我知道听起来有点疯狂。我只是想弄清楚这是否能以可靠的方式完成。
更新:jquery现在托管在微软的cdn上。
http://www.asp.net/ajax/cdn/
- 好问题。还有,很好的警告。太多了,所以答案是"不要这样做!"不是:"好吧,这是怎么做的。"
- 当然,第一个答案是"不要使用Google托管版本。":-)
- 当然,这是因为如果你想主持一个严肃的网站,你不依赖别人主持你的文件。
- @Bryan Migliorisi,我想twitter也没那么严重吧?但我承认他们和谷歌之间的问题就像一个月前谷歌倒闭时一样。
- 使用google或不使用google进行JSlib托管的优点是值得一提的,但在其他几个线程中已经讨论过。我在寻找有关JS加载延迟回退的技术答案。
- 如果有本地副本,为什么还要使用托管版本?
- @JoeChung:它很可能缓存在用户的系统中,从而加速了页面加载。节省我的带宽。使用谷歌的cdn。等。
- @乔:stackoverflow.com/questions/313409/…
- 另一个原因是它允许你在本地黑客攻击你的webapp,即使你离线。
- 这些答案背后的主要想法是"jquery是否加载失败?"如果是,stackoverflow.com/questions/950087/…。
- 也许从谷歌托管它也是一件好事,如果它失败了,从微软托管它,如果他们都失败了,打开本地文件?
- 出于学术目的,我们总是可以在从Google加载jquery之前先检查它是否在缓存中。如果检查它是否在缓存中,那么也值得查看加载的查询版本是否支持您的代码。如果不加载适当的版本,则不会发生冲突。对吗?
- 如果一个人正在开发一个Web应用程序,它可能需要在一个没有连接到Internet的内部网中运行。
- @ MauganRa。在中国还有stackoverflow.com/questions/19943588/…
- 有这么多像EDOCX1[0]这样的对cdn的调用很重要吗?我的意思是我看到webbrowser在同一个域同时发出请求的数量是有限制的?
你可以这样做:
1 2 3 | <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"> window.jQuery || document.write('<script src="/path/to/your/jquery"><\/script>'); |
这应该出现在页面的
另一个不使用谷歌托管jquery的原因是,在某些国家,谷歌的域名被禁止使用。
- 对。就像在伊朗一样。"我不是说谷歌很脆弱。有些情况下谷歌的拷贝会被屏蔽(例如在伊朗)。
- 我假设您希望在该文档中编写一个备用脚本标记。是否编写("")?
- 这是一个很好的观点,我不知道如何强制这些步骤以同步方式运行。
- @罗尼,是的,这就是诀窍。
- 在javascript中必须有某种方法来检查文件的存在,如果它返回400类状态消息,那么就可以下载本地脚本,但我不确定它是如何工作的,它尝试了一些示例,但它不适用于我。
- @罗尼,看我编辑过的问题。您可以使用google.load从google的站点加载jquery。这可能有助于迫使问题保持同步。
- @nosredna这个问题反过来又是哪个文件包含google.load方法,这个方法又由google托管。
- 你不能有本地版本的google.load吗?
- 是的,您可以从google.com/jsapi复制源代码。
- 我相信使用JSAPI的自托管版本会使一些Google服务无法使用。例如,clientlocation。
- 关于使其同步:谷歌甚至没有尝试在其典型的jsapi include设置中解决这个问题,这一事实使我认为它不仅极不可能是可修复的,而且影响极小。(参见code.google.com/apis/ajax/documentation/gettingstarted-第三个代码块)
- javascript下载是否已被阻止(同步)?因此,在我看来,复印件问题不会是个问题。
- 正如马特·谢尔曼所说,JavaScript下载应该已经是同步的了。否则,如果页面试图执行依赖于只下载了一半的库的内联脚本,或者在没有完全下载和执行库的情况下执行库扩展,则会出现许多问题。这也是雅虎yslow建议将javascript放在页面末尾的原因之一;这样它就不会阻止其他页面元素(包括样式和图像)的下载。至少,浏览器必须延迟执行才能按顺序执行。
- 来自验证器狂热者的小修补:在javascript中不允许使用字符串"",因为它可能被错误地解释为脚本标记的结尾(sgml短标记表示法)。改为执行"<'+"/script>"。干杯,
- 这个例子行不通。1)如果google ajax库不可用,在失败之前必须先暂停。这可能需要一段时间。在我测试断开计算机与网络的连接时,它只是尝试并尝试并没有超时。2)如果!jquery)将引发错误,因为jquery没有定义,所以javascript不知道如何处理它。
- 要测试jquery是否已加载,(!(window.jquery)工作正常,短接检查类型。
- 我认为这个表达是"傻瓜证明",但我可以弥补这一点。
- 请注意,当浏览器等待DNS或TCP超时时,此解决方案可能会中断您的页面30秒或更长时间。
- 短而健壮:snipplr.com/view/41234/&hellip;
- @Boldewyn:实际上,字符串
"</" 是允许的,但"</script" 是不允许的。当然,HTML4规范不允许"</" ,但从未实现过,它已经固定在"html5"中。 - @Ryan:
是阻塞的,除非指定 async 或defer 属性,或者通过javascript动态插入它们。请删除您的评论,因为它传播错误信息。 - 好吧,你可以用
"<\/script>" 来代替"</script>" ,它同样可以逃走。 - 不需要
unescape 的标签;使用 <\/script> 已经解决了验证错误。 - 我编辑了第一个src属性以不包含方案,所以现在src是//ajax.googleapis.com/ajax/…。这可以确保引用在HTTP和HTTPS上都有效,并且根据stackoverflow.com/questions/550038/&hellip;完全有效。
- 您应该将它放在之前,并将所有jquery代码放在该代码和之间,这样您的站点加载更快,不要将其放在头上。
- 我更喜欢本杰明的解决方案。
- 有人能给我解释一下为什么有一个
\/ ? - @Jayen读了评论。已经解释过了。
- @Kleinfreund,不是真的。注释只讨论转义和验证错误,而不讨论为什么是错误或如何解决错误。为什么所有的江户人都不需要逃走?为什么只有这个?此外,在答案中添加这样的解释将有助于改进答案,imho。
- @Jayen这个评论和这个。
- 还要记住,谷歌会用这个来追踪用户访问的网站。因此,如果你正在创建一个需要注意隐私的网站,那么托管几个小文件是为隐私付出的一个小代价。
- 本地回退确切何时加载?等待google jquery cdn完成需要多长时间?如果Google加载实际上已经完成,但只延迟了几毫秒,它会加载回退吗?(双jquery负载=不好)
- 对于我使用GoogleChrome 44的情况,document.write不起作用,我使用了以下一个var script=document.createElement("script");script.setattribute("type","text/javascript");script.setattribute("src","/path/to/your/jquery");document.head.appendchild(script);
- @Angshuguha这里的所有东西都与Chrome51和Firefox 47@MacOSX一起工作。也许这是与您的具体案例相关的代码,不过这是很好的选择。:)
- stackoverflow.com/a/39246792/622813<---适用于需要WordPress版本的用户。
迄今为止最简单、最干净的方法是:
1 2 | <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"> window.jQuery || document.write('<script src="path/to/your/jquery"><\/script>') |
- @JPP不适用于
XHTML 1.0 和HTML 4.01 。 - 人们一直要求我删除
type="text/javascript" 部分,所以对于那些为老浏览器编写HTML的人来说,请注意,现在必须将其添加到中。 - 是否可以操纵它从两个主机检查库?例如,如果已经下载了Google或Microsoft,则不下载?(同时仍提供本地回退)
- @Benjaminrh:
type="text/javascript" 在旧浏览器中也是不必要的,因为它们都默认为javascript。实际上,旧的浏览器会查看language 属性;但即便如此,如果缺少该属性,javascript也是默认的。 - @但我喜欢闪亮的验证徽章:)
- 其他.js库也可以这样做吗?
- @当然,为什么不呢
- @特洛伊木马是完全可能的,只需堆叠调用。请注意,此时您正在打开新的连接主机,因此HTTP管道可能会更快。…
这里有一些很好的解决方案,但对于本地文件,我想更进一步。
在谷歌确实失败的情况下,它应该加载一个本地源,但也许服务器上的物理文件不一定是最佳选择。我之所以提出这个问题,是因为我目前正在实现相同的解决方案,只是我想返回到由数据源生成的本地文件。
我这样做的原因是,我想在跟踪我从Google加载的内容和本地服务器上的内容时,有一点想法。如果我想更改版本,我想保持本地副本与我试图从Google加载的内容同步。在一个有很多开发人员的环境中,我认为最好的方法是自动化这个过程,这样所有人都可以做的就是更改配置文件中的版本号。
以下是我提出的理论上可行的解决方案:
- 在应用程序配置文件中,我将存储3个内容:库的绝对URL、JavaScriptAPI的URL和版本号
- 编写一个类,该类获取库本身的文件内容(从app config获取URL),并将其与名称和版本号存储在我的数据源中。
- 编写一个处理程序,将本地文件从数据库中拉出并缓存该文件,直到版本号更改为止。
- 如果它确实发生了更改(在我的应用程序配置中),我的类将根据版本号提取文件内容,将其保存为数据源中的新记录,然后处理程序将启动并提供新版本。
理论上,如果我的代码写得正确,我需要做的就是在我的应用程序配置中更改版本号,然后Viola!您有一个自动回退解决方案,并且不必维护服务器上的物理文件。
大家怎么想?也许这太过分了,但它可能是维护Ajax库的一种很好的方法。
橡子
- 如果你只是在为jquery做所有的工作,那么我会说这太过分了。但是,如果您已经为应用程序的其他部分准备了一些组件(例如,如果您已经从数据库加载了脚本),那么它看起来相当不错。
- +1.虽然我不相信这样做的好处能够证明开发时间和复杂性的合理性,但我认为这一点是彻底的、新颖的。
1
2
3
4
5
6
7
8
9
10
11
12
13if (typeof jQuery == 'undefined') {
// or if ( ! window.jQuery)
// or if ( ! 'jQuery' in window)
// or if ( ! window.hasOwnProperty('jQuery'))
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '/libs/jquery.js';
var scriptHook = document.getElementsByTagName('script')[0];
scriptHook.parentNode.insertBefore(script, scriptHook);
}在您尝试包含来自cdn的Google拷贝之后。
在HTML5中,不需要设置
type 属性。您也可以使用…
1window.jQuery || document.write('<script src="/libs/jquery.js"><\/script>');- +1看起来更干净。顶部有一个小的打字错误,我无法清除,因为在"未定义"后面有两个右括号。
- 第一个选项避免chrome警告
[Violation] Avoid using document.write(). 。 - 不幸的是,第一个选项似乎不同步加载。第二个选项是。
您可能希望最后使用本地文件。
现在看来jquery自己的cdn不支持https。如果是这样的话,那么您可能希望首先从那里加载。
下面是顺序:谷歌CDN=>微软cdn=>您的本地副本。
1
2
3
4
5
6<!-- load jQuery from Google's CDN -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
<!-- fallback to Microsoft's Ajax CDN -->
window.jQuery || document.write('<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.3.min.js">\x3C/script>')
<!-- fallback to local file -->
window.jQuery || document.write('<script src="Assets/jquery-1.8.3.min.js">\x3C/script>')- +1表示nice语法。
- 是否确实需要一次以上的回退?如果两者都处于脱机状态,用户将在看到您的网站之前等待一分钟以上。
- 脚本加载失败不需要1分钟,是吗?
- @geo1701和edward,真的不需要第三个。即使是一次回退也尚未被证明是可靠的。如果google api关闭,我还没有看到任何保证第一次尝试会失败。我经历了这样一个场景,内容交付网络(cdn)从未加载失败,从任何时候都无法呈现页面,如这里提到的:stevensounders.com/blog/2013/03/18/http archive jquery/&hellip;
有条件地加载最新/旧jquery版本和回退:
1
2
3
4
5
6
7
8<!--[if lt IE 9]>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">
window.jQuery || document.write('<script src="/public/vendor/jquery-legacy/dist/jquery.min.js">\x3C/script>')
<![endif]-->
<!--[if gte IE 9]><!-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js">
window.jQuery || document.write('<script src="/public/vendor/jquery/dist/jquery.min.js">\x3C/script>')
<!--<![endif]-->- 这与跨浏览器不兼容。
- 乔希,是的,是的。
- 步骤1:jquery是否加载失败?(检查
jQuery 变量)
如何在javascript中检查未定义的变量
- 步骤2:动态导入(备份)javascript文件
如何在另一个javascript文件中包含一个javascript文件?
由于谷歌的禁令问题,我更喜欢使用微软的cdnhttp://www.asp.net/ajaxlibrary/cdn.ashx
这是一个很好的解释!
还实现加载延迟和超时!
http://happyworm.com/blog/2010/01/28/a-simple-and-robust-cdn-failover-for-jquery-14-in-one-line/
- 仅链接的答案不有用,被认为是低质量的。考虑将相关的位复制到您的答案中,当然还有源的属性。
- @你在开玩笑吗?这个答案已经超过7年了,所以这样的评论是没有根据的。
- 是的,这是一个古老的答案。尽管他们的建议是有效的。仅在其他地方链接的答案可以删除。更多读者:meta.stackoverflow.com/q/8259
- 我完全同意,我对自己的建议持温和的态度——但7年后说这句话毫无意义。7年前,而不是7年后,它本应像那样得到缓和。
- @斯图亚特·斯科利纳——如果我7年前看过,我会的:)我发现自己在这里做了一些研究,并且第一次看到这个。很抱歉让你失望-我认为我们的工作是做网站的管理员,这有时意味着评论、编辑或改进旧的问题或答案…
对于使用ASP.NET MVC 5的用户,请在bundleconfig.cs中添加此代码以启用jquery的cdn:
1
2
3
4bundles.UseCdn = true;
Bundle jqueryBundle = new ScriptBundle("~/bundles/jquery","//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js").Include("~/Scripts/jquery-{version}.js");
jqueryBundle.CdnFallbackExpression ="window.jQuery";
bundles.Add(jqueryBundle);更新:结果这个答案是错误的。请参阅评论了解真正的解释。
你们大多数人的问题都得到了回答,但至于最后一部分:
What would be the danger of both copies coming through?
没有。你会浪费带宽,可能会增加几毫秒的时间下载第二个无用的拷贝,但如果它们都通过,就不会有实际的危害。当然,您应该使用上面提到的技术避免这种情况。
- 实际上,根据这个问题,两次加载jquery可能会导致很多问题。
- 为什么不自己测试它并手动加载jquery库两次呢?然后答案就会揭晓。
- 为什么它是如此错误?@shadowcat7您能更具体地描述它导致的问题吗?在您链接的问题中,我看到的唯一明确标识的问题是"清除所有以前加载的插件"。但这不应适用于连续两次加载同一个jquery文件,对吗?我这样问是因为这里针对本地回退的其他解决方案非常复杂,document.write在某些地方被认为是邪恶的。
我做了一个gist,如果jquery还没有加载,它应该动态地加载它;如果源代码失败,它将继续进行回退(从许多答案中缝合在一起):https://gist.github.com/tigerhawkvok/9673154
请注意,我计划保持更新的要点,但不是这个答案,因为它的价值!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91/* 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();
}我认为应该在字符串中转义最后一个
1
2<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js">
window.jQuery || document.write('<script src="js/jquery-2.0.0.min.js">\x3C/script>')谷歌托管的jquery
- 如果您关心旧的浏览器,主要是IE9之前的IE版本,那么这是最广泛兼容的jquery版本。
1<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">- 如果你不在乎老爷车,这辆车又小又快:
1<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js">备份/回退计划!
- 无论哪种方式,您都应该使用本地回退,以防google cdn失败(不太可能)或在您的用户访问您的网站的位置(稍微更可能)被阻止,例如伊朗或有时是中国。
1
2<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">
if (!window.jQuery) { document.write('<script src="/path/to/your/jquery"><\/script>'); }参考:http://websitespeedoptimizations.com/contentdeliverynetworkpost.aspx
- 注意:在不安全的协议上加载脚本会打开一个XSS攻击向量。
1if (typeof jQuery == 'undefined')) { ...或
1if(!window.jQuery){如果未加载cdn版本,则不起作用,因为浏览器将在这种情况下运行,并且在下载过程中仍会下载需要jquery的其余javascript,并返回错误。解决方案是通过这种情况加载脚本。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<script src="http://WRONGPATH.code.jquery.com/jquery-1.4.2.min.js" type="text/javascript"><!-- WRONGPATH for test-->
<script type="text/javascript">
function loadCDN_or_local(){
if(!window.jQuery){//jQuery not loaded, take a local copy of jQuery and then my scripts
var scripts=['local_copy_jquery.js','my_javascripts.js'];
for(var i=0;i<scripts.length;i++){
scri=document.getElementsByTagName('head')[0].appendChild(document.createElement('script'));
scri.type='text/javascript';
scri.src=scripts[i];
}
}
else{// jQuery loaded can load my scripts
var s=document.getElementsByTagName('head')[0].appendChild(document.createElement('script'));
s.type='text/javascript';
s.src='my_javascripts.js';
}
}
window.onload=function(){loadCDN_or_local();};- 我在Google Chrome缓存中测试脚本时发现了一个问题。因此,对于本地测试,只需将else部分中的src替换为s.src='my javascripts.js'+'?'+math.floor(math.random()*10001&zwnj;&8203;);
- 如果不加载cdn版本,alex的答案将不起作用,因为浏览器将运行在这种情况下,并且在下载过程中仍会下载需要jquery的其余javascript s,它返回错误->正在下载的javascript文件将阻止下一段代码的运行,因此这不是问题。
使用ASP.NET中的Razor语法,此代码提供回退支持并使用虚拟根目录:
1
2
3
4@{var jQueryPath = Url.Content("~/Scripts/jquery-1.7.1.min.js");}
<script type="text/javascript">
if (typeof jQuery == 'undefined')
document.write(unescape("%3Cscript src='@jQueryPath' type='text/javascript'%3E%3C/script%3E"));或制作助手(助手概述):
1
2
3
4@helper CdnScript(string script, string cdnPath, string test) {
@Html.Raw("<script src="http://ajax.aspnetcdn.com/" + cdnPath +"/" + script +"" type="text/javascript">" +
"<script type="text/javascript">" + test +" || document.write(unescape("%3Cscript src='" + Url.Content("~/Scripts/" + script) +"' type='text/javascript'%3E%3C/script%3E"));")
}像这样使用:
1
2@CdnScript("jquery-1.7.1.min.js","ajax/jQuery","window.jQuery")
@CdnScript("jquery.validate.min.js","ajax/jquery.validate/1.9","jQuery.fn.validate")- 我从来没有对Razor感兴趣,但它看起来像一个模糊器,除了它使代码更长而不是更短(它的长度是这个的两倍)。
- @马阿蒂努斯:这不是苹果对苹果的比较。您提到的Benjaminrh的答案是针对一个以cdn为宿主的脚本。使用
CdnScript 助手,每个脚本只需要一行代码。你拥有的脚本越多,回报就越大。 - 当然。。。这只是一个咆哮。不过,我想这不是最佳的方法。如果有什么失败,我会完全忽略cdn并切换到所有脚本的回退。我不确定这是否可行,因为我不知道装载是如何工作的。
- @Maaartinus:由于每个cdn脚本加载都可能独立失败,因此必须分别检查每个加载。在从cdn加载所有脚本和从本地加载所有脚本之后,没有可靠的方法进行单个cdn检查。
- 让我担心的是,cdn站点的故障导致了许多负载的等待时间。所以我想要一些像
try { for (Script s : ...) cdnLoad(s); } catch (...) { for (Script s : ...) ownLoad(s); } 的东西。把它翻译成一堆if 可能是一场噩梦。 - @Maaartinus:如果脚本被设计成要被多次加载,那么这种方法是有效的。否则,如果您有脚本A、B和C,以及从cdn加载的A和B,但C失败,您将得到A、B、A、B、C的加载序列,其中前两个从cdn加载,最后三个从web服务器加载。似乎您需要一个g
tryCdn 变量,初始设置为true。只有当tryCdn 仍然为真时,每个cdnLoad 方法才会首先尝试cdn,如果cdn加载失败,则将其设置为假。 - 这是有道理的!另外,在我的服务器看到一些失败之后,我会让它暂时避免使用cdn。
虽然编写EDOCX1[1]对于jquery回退似乎比较容易,但chrome在这种情况下给出了验证错误。所以我更喜欢打破"脚本"这个词。所以它变得像上面一样安全。
1
2
3
4
5<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.1.min.js">
if (typeof jQuery ==="undefined") {
window.jqFallback = true;
document.write("<scr"+"ipt src='http://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js'></scr"+"ipt>");
}对于长期问题,最好记录jquery回退。在上面的代码中,如果第一个cdn不可用,jquery将从另一个cdn加载。但您可能希望了解错误的cdn并永久删除它。(这种情况非常特殊)另外,最好记录回退问题。所以您可以使用Ajax发送错误的案例。由于没有定义jquery,所以应该对Ajax请求使用普通的javascript。
1
2
3
4
5
6
7
8
9<script type="text/javascript">
if (typeof jQuery === 'undefined' || window.jqFallback == true) {
// XMLHttpRequest for IE7+, Firefox, Chrome, Opera, Safari
// ActiveXObject for IE6, IE5
var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
var url = window.jqFallback == true ?"/yourUrl/" :"/yourUrl2/";
xmlhttp.open("POST", url, true);
xmlhttp.send();
}无法从您无法控制的外部数据存储中加载资源是很困难的。寻找丢失的函数是完全错误的,因为它可以避免超时,如本文所述:http://www.tech-101.com/support/topic/4499-issues-using-a-cdn/
您可以使用如下代码:
1
2<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js">
window.jQuery || document.write('<script type="text/javascript" src="./scripts/jquery.min.js">\x3C/script>')但也有一些库可用于为脚本设置几个可能的回退并优化加载过程:
- 篮球队
- 必需品
- 耶普诺普
实例:
篮球队我认为现在最好的变种。将在本地存储中调用脚本,这将加速下一次加载。最简单的呼叫:
1basket.require({ url: '/path/to/jquery.js' });这将返回一个承诺,您可以在错误时执行下一个调用,或者在成功时加载依赖项:
1
2
3
4
5
6
7
8basket
.require({ url: '/path/to/jquery.js' })
.then(function () {
// Success
}, function (error) {
// There was an error fetching the script
// Try to load jquery from the next cdn
});必需品
1
2
3
4
5
6
7
8
9
10
11
12
13
14requirejs.config({
enforceDefine: true,
paths: {
jquery: [
'//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min',
//If the CDN location fails, load from this location
'js/jquery-2.0.0.min'
]
}
});
//Later
require(['jquery'], function ($) {
});耶普诺普
1
2
3
4
5
6
7
8yepnope([{
load: 'http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js',
complete: function () {
if (!window.jQuery) {
yepnope('js/jquery-2.0.0.min.js');
}
}
}]);另一个回退将ajax.googleapis.com替换为cdnjs.cloudflare.com:
1
2
3
4
5
6
7
8
9
10
11
12
13(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 + '">');
}
})(document, window.jQuery || window.Zepto);- 通过在字符串中指定jquery版本,可以坚持使用它。
- 适用于不适用于HTML截图的资产管理
- 野外测试-适合中国用户
- 您能详细描述一下以下语句吗:"您不必关心jquery版本"?
- 这个版本是URL的一部分,它不可能被这种方法接触到…jquery/3.x.x/jquery.min.js
- 当jquery返回到版本4并引入向后不兼容的更改时,是否有可能导致中断?
- 我不这么认为。。。
- -1因为如果jquery引入了中断更改,那么这将导致中断,除非指定了版本,否则脚本尚不支持这些更改。
- @听着,我想你不明白退路。它会替换承载它的域,并且根本不接触文件名/版本。
- 抱歉,我没有看到你关于保持版本部分不变的评论。让我编辑它,这样我就可以撤回-1,因为我发现(显然不仅仅是我由其他人判断)你的答案有点混乱。回退机制对我来说显然很清楚,顺便说一句: