使用 Google 托管 jQuery 的最佳方式,但回退到我在 Google 上的托管库失败
尝试加载 Google 托管的 jQuery(或其他 Google 托管的libs),但如果 Google 尝试失败,则加载我的 jQuery 副本?
我并不是说谷歌很脆弱。 在某些情况下,谷歌副本会被屏蔽(例如在伊朗)。
我会设置一个计时器并检查 jQuery 对象吗?
两份副本都通过会有什么危险?
并不是真正寻找诸如“仅使用 Google 的”或“仅使用您自己的”之类的答案。 我理解这些论点。 我还了解到,用户很可能缓存了 Google 版本。 我正在考虑云的总体后备方案。
编辑:这部分添加...
由于 Google 建议使用 google.load 加载 ajax 库,并且完成后执行回调,我想知道这是否是序列化此问题的关键。
我知道这听起来有点疯狂。 我只是想弄清楚是否可以以可靠的方式完成。
更新:jQuery 现在托管在 Microsoft 的 CDN 上。
What would be a good way to attempt to load the hosted jQuery at Google (or other Google hosted libs), but load my copy of jQuery if the Google attempt fails?
I'm not saying Google is flaky. There are cases where the Google copy is blocked (apparently in Iran, for instance).
Would I set up a timer and check for the jQuery object?
What would be the danger of both copies coming through?
Not really looking for answers like "just use the Google one" or "just use your own." I understand those arguments. I also understand that the user is likely to have the Google version cached. I'm thinking about fallbacks for the cloud in general.
Edit: This part added...
Since Google suggests using google.load to load the ajax libraries, and it performs a callback when done, I'm wondering if that's the key to serializing this problem.
I know it sounds a bit crazy. I'm just trying to figure out if it can be done in a reliable way or not.
Update: jQuery now hosted on Microsoft's CDN.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(23)
您可以使用如下代码:
但也可以使用一些库来为脚本设置几个可能的后备并优化加载过程:
示例:
basket.js
我认为目前最好的变体。 将在本地存储中缓存您的脚本,这将加快下次加载的速度。 最简单的调用:
这将返回一个承诺,您可以在错误时执行下一个调用,或者在成功时加载依赖项:
RequireJS
yepnope
You can use code like:
But also there are libraries you can use to setup several possible fallbacks for your scripts and optimize the loading process:
Examples:
basket.js
I think the best variant for now. Will cach your script in the localStorage, that will speed up next loadings. The simplest call:
This will return a promise and you can do next call on error, or load dependencies on success:
RequireJS
yepnope
您永远不需要使用个人副本。 这是我完整的腰带和背带脚本。
You should never need to use a personal copy. Here is my full belt and braces script.
您可以这样实现:
这应该位于页面的
中,并且任何 jQuery 就绪事件处理程序都应该位于
中以避免错误(尽管这不是万无一失的!)。
不使用 Google 托管的 jQuery 的另一个原因是,在某些国家/地区,Google 的域名被禁止。
You can achieve it like this:
This should be in your page's
<head>
and any jQuery ready event handlers should be in the<body>
to avoid errors (although it's not fool-proof!).One more reason to not use Google-hosted jQuery is that in some countries, Google's domain name is banned.
迄今为止最简单、最干净的方法:
The easiest and cleanest way to do this by far:
这似乎对我有用:
它的工作方式是使用调用 http 的
google
对象://www.google.com/jsapi 加载到window
对象上。 如果该对象不存在,我们就假设访问 Google 失败。 如果是这种情况,我们使用document.write
加载本地副本。 (在本例中我使用自己的服务器,请使用您自己的服务器进行测试)。我还测试了
window.google.load
的存在 - 我可以还执行typeof
检查以查看事物是否是适当的对象或函数。 但我认为这确实有效。这只是加载逻辑,因为自从我发布了我正在测试的整个 HTML 页面以来,代码突出显示似乎失败了:
虽然我必须说,但我不确定这是否是您的网站访问者所关心的问题,您应该摆弄 < href="https://developers.google.com/speed/libraries/" rel="noreferrer">Google AJAX Libraries API 根本没有。
有趣的事实:我最初尝试在各种版本中使用 try..catch 块来实现此目的,但找不到像这样干净的组合。 我有兴趣看到这个想法的其他实现,纯粹作为练习。
This seems to work for me:
The way it works is to use the
google
object that calling http://www.google.com/jsapi loads onto thewindow
object. If that object is not present, we are assuming that access to Google is failing. If that is the case, we load a local copy usingdocument.write
. (I'm using my own server in this case, please use your own for testing this).I also test for the presence of
window.google.load
- I could also do atypeof
check to see that things are objects or functions as appropriate. But I think this does the trick.Here's just the loading logic, since code highlighting seems to fail since I posted the whole HTML page I was testing:
Though I must say, I'm not sure that if this is a concern for your site visitors you should be fiddling with the Google AJAX Libraries API at all.
Fun fact: I tried initially to use a try..catch block for this in various versions but could not find a combination that was as clean as this. I'd be interested to see other implementations of this idea, purely as an exercise.
如果您的网站上嵌入了 Modernizr.js,则可以使用内置的 yepnope.js 异步加载脚本 - 其中包括 jQuery(带有后备)。
这将从 Google-cdn 加载 jQuery。 然后检查 jQuery 是否加载成功。 如果不是(“nope”),则加载本地版本。 此外,您的个人脚本也会被加载 - “两者”表示加载过程的启动与测试结果无关。
当所有加载过程完成时,将执行一个函数,在“MyApp.init”的例子中。
我个人更喜欢这种异步脚本加载的方式。 由于我在构建网站时依赖 Modernizr 提供的功能测试,因此无论如何我都将其嵌入到网站中。 所以实际上没有任何开销。
If you have modernizr.js embedded on your site, you can use the built-in yepnope.js to load your scripts asynchronously - among others jQuery (with fallback).
This loads jQuery from the Google-cdn. Afterwards it's checked, if jQuery was loaded successfully. If not ("nope"), the local version is loaded. Also your personal scripts are loaded - the "both" indicates, that the load-process is iniated independently from the result of the test.
When all load-processes are complete, a function is executed, in the case 'MyApp.init'.
I personally prefer this way of asynchronous script loading. And as I rely on the feature-tests provided by modernizr when building a site, I have it embedded on the site anyway. So there's actually no overhead.
这里有一些很好的解决方案,但我想在本地文件方面更进一步。
在 Google 确实失败的情况下,它应该加载本地源,但服务器上的物理文件不一定是最佳选择。 我提出这个问题是因为我目前正在实现相同的解决方案,只是我想回退到由数据源生成的本地文件。
我这样做的原因是,在跟踪我从 Google 加载的内容与本地服务器上加载的内容时,我想有一些想法。 如果我想更改版本,我需要使本地副本与我尝试从 Google 加载的内容保持同步。 在有许多开发人员的环境中,我认为最好的方法是自动化此过程,这样人们所要做的就是更改配置文件中的版本号。
这是我提出的解决方案,理论上应该有效:
理论上,如果我的代码编写正确,我需要做的就是更改我的应用程序配置中的版本号,然后中提琴! 您有一个自动化的后备解决方案,并且您不必在服务器上维护物理文件。
大家觉得怎么样? 也许这有些过头了,但它可能是维护 AJAX 库的一种优雅方法。
橡子
There are some great solutions here, but I'll like to take it one step further regarding the local file.
In a scenario when Google does fail, it should load a local source but maybe a physical file on the server isn't necessarily the best option. I bring this up because I'm currently implementing the same solution, only I want to fall back to a local file that gets generated by a data source.
My reasons for this is that I want to have some piece of mind when it comes to keeping track of what I load from Google vs. what I have on the local server. If I want to change versions, I'll want to keep my local copy synced with what I'm trying to load from Google. In an environment where there are many developers, I think the best approach would be to automate this process so that all one would have to do is change a version number in a configuration file.
Here's my proposed solution that should work in theory:
In theory, if my code is written properly, all I would need to do is change the version number in my app config then viola! You have a fallback solution which is automated, and you don't have to maintain physical files on your server.
What does everyone think? Maybe this is overkill, but it could be an elegant method of maintaining your AJAX libraries.
Acorn
当您尝试包含来自 CDN 的 Google 副本后。
在 HTML5 中,您不需要设置
type
属性。您还可以使用...
After you attempt to include Google's copy from the CDN.
In HTML5, you don't need to set the
type
attribute.You can also use...
您可能想使用本地文件作为最后的手段。
好像现在jQuery自己的CDN不支持https。 如果是这样,那么您可能需要先从那里加载。
所以这是顺序:
谷歌 CDN =>
微软CDN =>
您的本地副本。
You might want to use your local file as a last resort.
Seems as of now jQuery's own CDN does not support https. If it did you then might want to load from there first.
So here's the sequence:
Google CDN =>
Microsoft CDN =>
Your local copy.
有条件地加载最新/旧版 jQuery 版本并回退:
Conditionally load latest/legacy jQuery version and fallback:
jQuery
变量)如何检查 JavaScript 中未定义的变量
如何将一个 JavaScript 文件包含在另一个 JavaScript 文件中?
jQuery
variable)How to check a not-defined variable in JavaScript
How do I include a JavaScript file in another JavaScript file?
由于Google的禁止问题我更喜欢使用微软的cdn
http://www.asp.net/ajaxlibrary/cdn.ashx
Because of the Google's banning problem I prefer to use Microsoft's cdn
http://www.asp.net/ajaxlibrary/cdn.ashx
对于使用 ASP.NET MVC 5 的用户,请在 BundleConfig.cs 中添加以下代码以启用 jquery 的 CDN:
For those people using ASP.NET MVC 5, add this code in your BundleConfig.cs to enable the CDN for jquery:
更新:
事实证明这个答案是错误的。 真正的解释请看评论。
大多数人的问题已经得到解答,但至于最后一部分:
真的没有。 您会浪费带宽,可能会增加几毫秒的时间来下载第二个无用的副本,但如果它们都通过了,则不会造成实际损害。 当然,您应该使用上述技术来避免这种情况。
UPDATE:
This answer turned out to be wrong. Please see the comments for the real explanation.
Most of you question has been answered, but as for the final part:
None really. You'd waste bandwidth, might add some milliseconds downloading a second useless copy, but there's not actual harm if they both come through. You should, of course, avoid this using the techniques mentioned above.
我做了一个要点,如果尚未加载,则应该动态加载 jQuery,如果源失败,它将继续进行后备(由许多答案缝合在一起): https://gist.github.com/tigerhawkvok/9673154
请注意,我计划更新要点,但不更新这个答案,无论它的价值如何!
I made a Gist that should dynamically load jQuery if it isn't already loaded, and if the source fails, it proceeds onto fallbacks (stitched together from many answers): https://gist.github.com/tigerhawkvok/9673154
Please note I plan to keep the Gist updated but not this answer, for what it's worth!
Google 托管 jQuery
< strong>备份/回退计划!
参考: http://websitespeedoptimizations.com/ContentDeliveryNetworkPost.aspx
Google Hosted jQuery
Backup/Fallback Plan!
Reference: http://websitespeedoptimizations.com/ContentDeliveryNetworkPost.aspx
我认为应该避开最后一个< 到字符串中的 \x3C。 当浏览器看到 时,它认为这是脚本块的结尾(因为 HTML 解析器不了解 JavaScript,它无法区分仅出现在字符串中的内容和实际上意味着结束脚本的内容元素)。 因此,在 HTML 页面内的 JavaScript 中逐字出现将(在最好的情况下)导致错误,并且(在最坏的情况下)会成为一个巨大的安全漏洞。
I consider that should escape the last < to \x3C in string. When the browser sees , it considers this to be the end of the script block (since the HTML parser has no idea about JavaScript, it can't distinguish between something that just appears in a string, and something that's actually meant to end the script element). So appearing literally in JavaScript that's inside an HTML page will (in the best case) cause errors, and (in the worst case) be a huge security hole.
或者
如果未加载 cdn 版本,则不起作用,因为浏览器将运行这种情况,并且在此期间仍然下载需要 jQuery 的其余 javascript,并返回错误。 解决方案是通过该条件加载脚本。
Or
Will not works if cdn version not loaded, because browser will run through this condition and during it still downloading the rest of javascripts which needs jQuery and it returns error. Solution was to load scripts through that condition.
使用 ASP.NET 中的 Razor 语法,此代码提供后备支持并可与虚拟根一起使用:
或者创建一个帮助程序 (帮助器概述):
并像这样使用它:
Using Razor syntax in ASP.NET, this code provides fallback support and works with a virtual root:
Or make a helper (helper overview):
and use it like this:
尽管编写
document.write("")
对于 jQuery 退避来说似乎更容易,但 Chrome 在这种情况下会给出验证错误。 所以我更喜欢打破“脚本”这个词。 所以像上面那样变得更安全。对于长期问题,最好记录 JQuery 回退。 在上面的代码中,如果第一个 CDN 不可用,则从另一个 CDN 加载 JQuery。 但您可能想知道错误的 CDN 并将其永久删除。 (这种情况是非常特殊的情况)此外,最好记录后备问题。 因此您可以使用 AJAX 发送错误的案例。 由于未定义 JQuery,因此您应该使用普通 javascript 进行 AJAX 请求。
Although writing
document.write("<script></script>")
seems easier for jQuery backoff, Chrome gives validation error on that case. So I prefer breaking "script" word. So it becomes safer like above.For long term issues, it would be better to log JQuery fallbacks. In the code above, if first CDN is not available JQuery is loaded from another CDN. But you could want to know that erroneous CDN and remove it permanently. (this case is very exceptional case) Also it is better to log fallback issues. So you can send erroneous cases with AJAX. Because of JQuery isn't defined, you should use vanilla javascript for AJAX request.
无法从您无法控制的外部数据存储加载资源是很困难的。 寻找缺失的函数作为避免超时的方法是完全错误的,如下所述:
http://www.tech-101.com/支持/主题/4499-issues-using-a-cdn/
The inability to load the resource from an external data store beyond your control is difficult. Looking for missing functions is totally fallacious as a means to avoid suffering a timeout, as described herein:
http://www.tech-101.com/support/topic/4499-issues-using-a-cdn/
几乎所有公共 CDN 都非常可靠。 但是,如果您担心 google 域被阻止,那么您可以简单地回退到替代的 jQuery CDN。 但是,在这种情况下,您可能更愿意采取相反的方式,并使用其他 CDN 作为您的首选,然后回退到 Google CDN,以避免失败的请求和等待时间:
Almost all public CDNs are pretty reliably. However, if you are worried about blocked google domain, then you can simply fallback to an alternative jQuery CDN. However, in such a case, you may prefer to do it opposite way and use some other CDN as your preferred option and fallback to Google CDN to avoid failed requests and waiting time:
还有一个后备方案,将 ajax.googleapis.com 替换为 cdnjs.cloudflare.com:
Yet another fallback that replaces ajax.googleapis.com with cdnjs.cloudflare.com: