引用外部JavaScript与托管我自己的副本


42

假设我有一个使用jQuery的网络应用。更好的做法是将必要的javascript文件与网站文件一起托管在我自己的服务器上,还是在jQuery的CDN上引用它们(例如:http : //code.jquery.com/jquery-1.7.1.min.js) ?

我可以看到双方的优点:

  • 如果是在我的服务器上,那就少了一个外部依赖性。如果jQuery崩溃或更改了其托管结构或类似的东西,那么我的应用程序就会崩溃。但是我觉得这种情况不会经常发生。必须有许多小型站点这样做,并且jQuery团队将希望避免破坏它们。
  • 如果是在我的服务器上,那是一个比别人少的外部参考,有人可以称之为安全问题
  • 如果它是从外部引用的,那么我不必担心为文件提供服务的带宽(尽管我知道不是很多)。
  • 如果从外部引用它,而我正在将该网站部署到许多需要拥有所有文件副本的服务器上,那么我要记住要复制/更新的文件要少一个。

前两点仅在您担心Google崩溃或被黑客入侵时适用。
user16764 2012年

1
@ user16764-否则他们出于某种原因(政治人士,知道)删除了jQuery副本。
Jefferson先生2012年

2
另一个原因是隐私。使用第三方托管的内容使第三方可以跟踪他们不容易退出的用户。
伊恩·纽森

也有一些CDN特别是Google主机有时会限制来自特定国家
地区

Answers:


58

您应该同时执行以下两项操作:

首先从CDN(例如Google的 CDN)托管,因为它的正常运行时间可能比您自己的站点更长,并且配置为具有最快的响应时间。此外,访问链接到CDN的页面的任何人都将使用其文件的缓存副本,因此他们甚至不必重新下载副本,从而使初始加载速度更快。

然后在CDN发生故障(不太可能,但安全是安全的)的情况下,向您自己的服务器添加一个后备引用。回退相对容易理解,但需要进行自定义以适合所使用的脚本:

<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
<script>
    if (!window.jQuery) document.write('<script src="/path/to/jquery-ver.sion.min.js"><\/script>');
</script>

确保您没有</script><script>元素内的任何地方写东西,因为它会关闭HTML元素并导致脚本失败。简单的解决方法是使用反斜杠作为转义符:<\/script>


同时做这两个的另一个原因:

如果您选择一个流行的CDN,则极少会出现停机时间,但是在不远的将来(根据摩尔定律,从现在起约18个月),托管格式会发生变化,或者地址会进行调整,或者网络放置在付费专区或其他任何设施的后面,则您的链接可能无法再按原样工作。如果您使用后备,那么在您不得不回头浏览曾经创建的每个网站并更改CDN链接之前,它会给您一些时间来适应任何新的托管格式。


两者都做的另一个原因:

最近,我遭受了一系列互联网中断的打击。我能够继续在本地进行脚本资源本地链接的项目上工作,然后我很快发现,有许多项目需要链接本地副本。


+1为您提供CDN的好处,并涵盖了潜在的陷阱。
2012年

5
正常运行时间有什么关系?如果他的网站没有启动,那么在线上js几乎不是好处:)
Boris Yankov 2012年

3
@BorisYankov,如果CDN断开并且您的站点已启动,并且您未使用本地备用,则您的站点将无法工作。这就是正常运行时间的意义。如果您的网站已关闭,则您的网站已关闭,本地副本将无关紧要。
zzzzBov 2012年

CDN也将到处都有服务器,因此您将从最近的节点获取资源。
hanzolo 2014年

35

我遇到了同样的问题,然后阅读了这篇文章,然后就被让Google托管我的jQuery库的想法所吸引。

本文介绍了让您的图书馆由Google的内容交付网络(CDN)托管的主要好处:

  • 降低的延迟 -不在您服务器附近的用户能够比从强迫您从任意位置的服务器下载jQuery更快地从Google下载jQuery。
  • 并行性提高 -浏览器限制了可以同时建立的连接数。根据哪个浏览器,此限制可能低至每个主机名两个连接。使用Google AJAX库CDN可以消除对您网站的一个请求,从而可以并行下载更多本地内容。
  • 更好的缓存 -使用Google AJAX库,您的用户可能根本不需要下载jQuery。另一方面,如果要在本地托管jQuery,则用户必须至少下载一次。您的每个用户可能已经在其浏览器的缓存中拥有许多相同的jQuery副本,但是当他们访问您的网站时,这些jQuery副本将被忽略。

至于您列为托管自己的库的专家的两个要点,请记住,这是由Google托管的云版本,并且Google知道它们在做什么,并且就可用性和安全性而言值得信赖。但是,@ zzzzBov在回答这个问题时非常有意思,他建议还存储该库的本地副本,并在由于某种原因而无法访问CDN版本的情况下,默认使用该本地副本。


4
啊,我敢肯定,与Google相比,托管静态资产能做得更好。;)
Xeoncross 2012年

不同时使用两者(CDN +本地后备)只是草率。真可惜,这是恕我直言的最高答案。
2012年

@qes很公平,我在回答的末尾添加了一个新句子。
CFL_Jeff 2012年

17

我个人从http://html5boilerplate.com/获得了提示

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="includes/js/libs/jquery-1.6.1.min.js"%3E%3C/script%3E'))</script>

这会从Google提取主要的jQuery文件,但是如果由于某种原因未加载它,则下一行将从您自己的服务器加载它。


5
这具有让您脱机开发的额外好处。
RSG 2012年

使用协议相对URL不再像以前那样有用(请参阅paulirish.com/2010/the-protocol-relative-url)。在这里只键入是合理的https://
GKFX

5

最好使用CDN,如果该CDN恰好是Google,那就更好了-正如@CFL_Jeff和@Morons都指出的那样。

我要添加此答案以指出在指向其他位置时经常被忽略的某些内容,从而避免了混合内容警告。考虑使用无协议URL,例如:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js" type="text/javascript">
</script>

使用无协议URL时仍然存在一些支持问题,因此请仔细阅读“ 我可以将所有http://链接更改为//吗?”上的答案SO,但至少要尝试以某种方式处理潜在的混合内容警告。


4

您应该将其引用到Google的API库 ..

这样做的主要原因是为了加快页面加载速度。如果用户已经访问了另一个引用相同库的站点,则该站点将已经存储在浏览器缓存中,并且根本不需要下载


0

我可能是错的,但是实现document.write会覆盖DOM的所有内容。由于将JavaScript文件放在正文末尾是一种很好的做法,

我根据先前的答案提出以下方法:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">

if(!window.jQuery)
{
    //Creates the script element
    var script = document.createElement('script'); 
    //Adds the type attribute with "text/javascript" value
        script.setAttribute('type', 'text/javascript'); 
    //Adds the source attribute and populates it
        script.setAttribute('src', 'Put_The_Relative_Path_To_Your_JavaScript_File_Here'); 
    //Adds it to the end of the body, as it is good practice, to prevent render-blocking.  
    document.body.appendChild(script);

}

//Note that there's no need for you to verify with an onload function, since all scripts
//must be loaded before going to the next one! 

</script>

0

我想补充一点是,托管本地副本是一种最佳做法,因为以上内容均未说明与安全姿势有关的任何内容,因此地理位置和严格的白名单功能势在必行。假定不在本地托管该文件可能会降低客户端的安全性。


列入黑名单或以其他方式限制jQuery的任何一个CDN的安全策略将破坏很多网站,不仅是问询者的网站。换句话说,有更大的问题要担心。

2
@Snowman ...就像中国的大型防火墙一样(它经常破坏使用CDN编写脚本的Stack Exchange网站)?
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.