使用谷歌托管的jQuery的最佳方式,但回到我在谷歌上的托管库失败

Nos*_*dna 1012 jquery cdn google-ajax-libraries

尝试在Google(或其他Google托管的lib)上加载托管jQuery的好方法,但如果Google尝试失败,请加载我的jQuery副本?

我不是说谷歌是片状的.有些情况下谷歌副本被封锁(例如在伊朗).

我会设置一个计时器并检查jQuery对象吗?

这两份副本的危险是什么?

并不是真的在寻找"只使用谷歌"或"只使用自己的"等答案.我理解这些论点.我也理解用户可能会缓存Google版本.我正在考虑一般的云回退.


编辑:这部分补充......

由于Google建议使用google.load加载ajax库,并在完成后执行回调,我想知道这是否是序列化此问题的关键.

我知道这听起来有点疯狂.我只想弄清楚它是否可以以可靠的方式完成.


更新:jQuery现在托管在微软的CDN上.

http://www.asp.net/ajax/cdn/

Ron*_*ony 804

你可以这样做:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script>
   window.jQuery || document.write('<script src="/path/to/your/jquery"><\/script>');
</script>
Run Code Online (Sandbox Code Playgroud)

这应该在你的页面中,<head>并且任何jQuery ready事件处理程序都应该<body>避免错误(尽管它不是万无一失的!).

使用Google托管的jQuery的另一个原因是,在某些国家/地区,Google的域名被禁止.

  • 正如Matt Sherman所说,Javascript下载已经是同步的.否则,如果页面试图执行依赖于仅下载了一半的库的内联脚本,或者在没有完全下载和执行库的情况下执行库扩展,则会出现许多问题.这也是Yahoo YSlow建议在页面末尾放置javascript的原因之一; 这样它就不会阻止下载其他页面元素(包括样式和图像).至少,浏览器必须延迟执行才能顺序发生. (68认同)
  • 来自验证器狂热者的小修复:JavaScript中不允许使用字符串'</',因为它可能被误解为脚本标记的末尾(SGML短标记符号).改为'<'+'/ script>'.干杯, (42认同)
  • 是不是javascript下载阻塞(同步)?因此,双重复印问题对我来说不是问题. (35认同)
  • 要测试是否加载了jQuery,(!window.jQuery)工作正常,并且短路然后检查类型. (32认同)
  • 这个例子不起作用.1)如果谷歌ajax库不可用,它必须先失效才能失败.可能还要等一下.在我断开计算机与网络连接的测试中,它只是尝试并尝试过并且没有超时.2)如果(!jQuery)将抛出错误,因为jQuery没有定义,所以Javascript不知道如何处理它. (8认同)
  • 简短而强大:http://snipplr.com/view/41234/use-google-cdn-jquery-but-fallback-to-local-copy/ (3认同)
  • @Ryan:`<script>`是阻塞的,除非你指定`async`或`defer`属性,或者你通过JavaScript动态插入它们.请删除您的评论,因为它传播错误信息. (3认同)
  • @Nosredna这个问题依次是哪个文件包含google.load方法,再次托管谷歌 (2认同)
  • 我认为表达是"万无一失",但我可以做到这一点. (2认同)
  • 请注意,当浏览器等待DNS或TCP超时时,此解决方案可能会使页面中断30秒或更长时间. (2认同)
  • 好吧,而不是`"</ script>"`,你可以做``<\/script>"`,它同样逃脱它. (2认同)
  • 我编辑了第一个src属性以不包含该方案,所以现在src是//ajax.googleapis.com/ajax/...这确保了引用在HTTP和HTTPS上都有效,并且每个http:// stackoverflow完全有效.COM /问题/ 550038/IS-IT-有效更换的-HTTP-WITH-IN-A-脚本-SRC-HTTP (2认同)
  • 我更喜欢BenjaminRH的解决方案. (2认同)

Ben*_*nRH 334

迄今为止最简单,最干净的方法:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="path/to/your/jquery"><\/script>')</script>
Run Code Online (Sandbox Code Playgroud)

  • @BenjaminRH:`type ="text/javascript"`在旧浏览器中也是不必要的,因为它们都默认为Javascript._Really_旧版浏览器查看了`language`属性; 但即使这样,如果缺少属性,Javascript也是默认值. (6认同)
  • 人们不断要求我删除`type ="text/javascript"`部分,所以对于为旧浏览器编写html的人,请注意你现在必须添加它. (5认同)
  • @Trojan完全可能,只需堆叠通话.请注意,此时您正在打开新连接主机,因此HTTP流水线操作可能会更快....`<script src ="// cdn1.com/jquery.js"> </ script> <script> window.jQuery || document.write('<script src ="// cdn2.com/jquery.js"> <\/script>')</ script> <script> window.jQuery || document.write('<script src ="local/jquery.js"> <\/script>')</ script>` (3认同)

art*_*ung 75

这似乎对我有用:

<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
// has the google object loaded?
if (window.google && window.google.load) {
    google.load("jquery", "1.3.2");
} else {
    document.write('<script type="text/javascript" src="http://joecrawford.com/jquery-1.3.2.min.js"><\/script>');
}
window.onload = function() {
    $('#test').css({'border':'2px solid #f00'});
};
</script>
</head>
<body>
    <p id="test">hello jQuery</p>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

它的工作方式是使用google调用http://www.google.com/jsapiwindow对象加载到对象上.如果该对象不存在,我们假设对Google的访问失败.如果是这种情况,我们使用加载本地副本document.write.(在这种情况下,我使用自己的服务器,请使用您自己的服务器进行测试).

我也测试是否存在window.google.load- 我也可以typeof检查一下事物是对象还是函数.但我认为这就是诀窍.

这里只是加载逻辑,因为代码突出显示似乎失败,因为我发布了我正在测试的整个HTML页面:

if (window.google && window.google.load) {
    google.load("jquery", "1.3.2");
} else {
    document.write('<script type="text/javascript" src="http://joecrawford.com/jquery-1.3.2.min.js"><\/script>');
}
Run Code Online (Sandbox Code Playgroud)

虽然我必须说,我不确定如果这对您的网站访问者来说是一个问题,那么您应该摆弄Google AJAX Libraries API.

有趣的事实:我最初尝试在各种版本中使用try..catch块,但找不到像这样干净的组合.我有兴趣看到这个想法的其他实现,纯粹作为练习.

  • 我们最近转而使用Google作为jQuery主机; 如果我们从被阻止的用户那里得到任何错误报告,我将使用您的答案变体来重构我们的客户端代码.好答案! (2认同)

Ema*_*uge 30

如果您的站点上嵌入了modernizr.js,则可以使用内置的yepnope.js异步加载脚本 - 其他jQuery(带回退).

Modernizr.load([{
    load : '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'
},{
    test : window.jQuery,
    nope : 'path/to/local/jquery-1.7.2.min.js',
    both : ['myscript.js', 'another-script.js'],
    complete : function () {
        MyApp.init();
    }
}]);
Run Code Online (Sandbox Code Playgroud)

这会加载来自Google-cdn的jQuery.然后检查,如果jQuery成功加载.如果不是("nope"),则加载本地版本.此外,您的个人脚本也会被加载 - "both"表示加载过程与测试结果无关.

当所有加载过程完成后,在"MyApp.init"的情况下执行一个函数.

我个人更喜欢这种异步脚本加载方式.因为我依赖于现代化建设网站时提供的功能测试,所以无论如何我都将它嵌入到网站上.所以实际上没有开销.

  • 我想你错过了这个问题的重点 - 你如何从CDN加载moernizr脚本? (2认同)
  • 我不建议从CDN加载Modernizr.应该从modernizr.com获得最小的自定义构建. (2认同)
  • 所以此选项获得+16,而其他选项获得的是500/200 +.但这听起来很不错.是否因为依赖Modernizer而不受欢迎?我碰巧在我们的网站上使用了Modernizer,所以如果这比其他答案更好,有人可以让我知道吗?我是JQuery的新手,所以澄清是值得赞赏的. (2认同)
  • 在答案的时候,这是一个非常好的选择,但截至2015年,`yepnope.js`已被弃用.见http://stackoverflow.com/questions/33986561/modernizr-load-deprecated-yepnope-js-deprecated-now-what (2认同)

Aco*_*orn 21

这里有一些很好的解决方案,但我想进一步了解本地文件.

在Google确实失败的情况下,它应该加载本地源,但服务器上的物理文件可能不一定是最佳选择.我提出这个问题是因为我目前正在实现相同的解决方案,只是我想回到由数据源生成的本地文件.

我的理由是,在跟踪我从Google加载的内容与本地服务器上的内容时,我想要有一些想法.如果我想更改版本,我会希望保持本地副本与我尝试从Google加载的内容同步.在有许多开发人员的环境中,我认为最好的方法是自动执行此过程,以便所有人都必须做的是更改配置文件中的版本号.

这是我提出的理论上应该有效的解决方案:

  • 在应用程序配置文件中,我将存储3件事:库的绝对URL,JavaScript API的URL和版本号
  • 编写一个获取库本身文件内容的类(从app config获取URL),将其存储在我的数据源中,并附上名称和版本号
  • 编写一个处理程序,将我的本地文件从数据库中提取出来并缓存该文件,直到版本号发生变化.
  • 如果它确实发生了变化(在我的应用程序配置中),我的类将根据版本号提取文件内容,将其保存为我的数据源中的新记录,然后处理程序将启动并提供新版本.

理论上,如果我的代码写得正确,我需要做的就是更改我的应用程序配置中的版本号然后中提琴!您有一个自动化的后备解决方案,您无需在服务器上维护物理文件.

每个人都在想什么?也许这有点矫枉过正,但它可能是一种维护AJAX库的优雅方法.

橡子


ale*_*lex 20

if (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);

}
Run Code Online (Sandbox Code Playgroud)

在您尝试从CDN中包含Google副本之后.

在HTML5中,您无需设置type属性.

你也可以用......

window.jQuery || document.write('<script src="/libs/jquery.js"><\/script>');
Run Code Online (Sandbox Code Playgroud)

  • +1看起来更清洁.在顶部有一个小错字,我无法清除,因为它'ery minor''undefined'之后的两个右括号 (2认同)

Edw*_*san 10

您可能希望将本地文件用作最后的手段.

似乎现在jQuery自己的CDN不支持https.如果它确实你那么可能想先从那里加载.

所以这是序列:Google CDN => Microsoft CDN =>您的本地副本.

<!-- load jQuery from Google's CDN -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 
<!-- fallback to Microsoft's Ajax CDN -->
<script> window.jQuery || document.write('<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.3.min.js">\x3C/script>')</script> 
<!-- fallback to local file -->
<script> window.jQuery || document.write('<script src="Assets/jquery-1.8.3.min.js">\x3C/script>')</script> 
Run Code Online (Sandbox Code Playgroud)


nei*_*ker 6

有条件地加载最新/遗留的jQuery版本和后备:

<!--[if lt IE 9]>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="/public/vendor/jquery-legacy/dist/jquery.min.js">\x3C/script>')</script>
<![endif]-->
<!--[if gte IE 9]><!-->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="/public/vendor/jquery/dist/jquery.min.js">\x3C/script>')</script>
<!--<![endif]-->
Run Code Online (Sandbox Code Playgroud)


Ser*_*dar 5

由于谷歌的禁止问题,我更喜欢使用微软的cdn http://www.asp.net/ajaxlibrary/cdn.ashx


nin*_*cko 5

  • 第1步:jQuery无法加载吗?(检查jQuery变量)

如何在JavaScript中检查未定义的变量

  • 第2步:动态导入(备份)javascript文件

如何在另一个JavaScript文件中包含JavaScript文件?