引用CDN内容的方法总结
1.1.1 摘要
CDN相信大家都听说过,甚至使用过相关的技术,也许有些人会回答“没有听说过和使用过该技术”,真的是这样吗?
CDN的全称是Content Delivery Network,即内容分发网络。其目的是通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的网络"边缘",使用户可以就近取得所需的内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
看完上面一大串的定义,我们可以把CDN简单的描述为:内容分发,解决网络拥挤和提供网站相应速度。
其实,CDN并不神秘甚至我们在日常开发过程中常常使用到该技术,例如:引用网络脚本库(如:jQuery)和网络图片资源等。
我们经常发现许多网站都从Google的CDN中引用相应的Javascript库,但很多网站都没有考虑如果CDN内容加载失败的情况,我们并不是说Google的CDN很脆弱,只是不怕万一只怕一万。
在接下来的博文中,我们将想大家介绍防范CDN内容加载的方法。
目录
- 基本方法
- HTML5 Boilerplate中的解决方法
- Javascript加载器
- ASP.NET Web Form 4.5
- AspNet.ScriptManager.jQuery包
- ASP.NET Web Optimization包
1.1.2 正文
基本方法
检查CDN内容是否加载成功的基本的方法,我们可以在脚本代码后添加代码判断该类型或变量是否存在,如果不存证明CDN加载失败,那么我们的程序就应该加载本地脚本,下面我们以加载jQuery库为例,具体实现如下:
- <!-- Adds google cdn reference -->
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
- <!-- Cdn fail refers to local library -->
- <script type="text/javascript">
- if (typeof jQuery == 'undefined') {
- document.write(unescape("%3Cscript src='js/jquery-2.0.0.min.js' type='text/javascript'%3E%3C/script%3E"));
- }
- </script>
上面,我们引用了Google CDN的jQuery库,接着我们在脚本代码后添加了一个if语句来判断jQuery库是否加载成功,如果没有加载成功我们动态加载本地jQuery库。
其中,我们在document.write方法中直接使用了URL编码,把“<”编码为“%3C”,接着我们再使用unescape()方法把字符串还原过来。
图1字符编码
上图,我们通过unescape()方法把字符串转换回来,我们可以看到输出是一个正常的脚本引用代码。
现在,我们有一个疑问就是“为什么不使用常规字符,而是要使用字符编码呢?”,其实这是有原因的,这意味着我们代码将可以在XML、XHTML或HTML中正常运行,而无需把代码包含在CDATA中(具体请参考这里)。
HTML5 Boilerplate中的解决方法
接下来,我们将介绍使用“协议省略”的引用地址和简化本地加载代码,在介绍之前,首先让我们了解使用“协议省略”的引用地址的优点。
我们知道使用安全的引用地址对于确保信息安全是无可厚非的,但过度地使用SSL缓存静态资源例如:jQuery库,也会导致加载的性能降低;出于同样的原因浏览器需要对这些资源进行加密,而且大多数浏览器默认不缓存通过SSL方式获取的文件。
更糟糕的是,即使用户已经有一个本地缓存副本在磁盘上,但通过HTTP请求从Google的CDN获取jQuery文件,不能被同一请求不同协议HTTPS使用,也就是说,对于同一请求不同协议要保存两个缓存文件。
Http请求的URL地址:
http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js
下面是使用Https请求的URL地址:
https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js
当我们在常规的Http页面中通过Https方式来引用Google CDN的jQuery库将导致缓存性能下降,我们应该尽量避免在Http页面中引用不必要的Https内容。
在RFC3986中的第4.2节规定合法的URL省略了协议(Http或Http)还是合法的,当一个URL的协议被省略时,浏览器将使用基本的文档的协议,通过这种方式,我们可以更加灵活地指定URL地址。所以我们可以通过以下的方式引用jQuery库。
- <!-- Adds protocol-less google cdn reference -->
- <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
上面的代码看起来奇怪,但“协议省略”的网址是引用第三方内容的最好的方式,它可以通过Http或Https引用。
当页面加载时,对于非加密请求脚本会通过Http方式引用并且缓存起来,以此同时对于加密请求脚本会根据“协议省略”方式使用Https引用内容,所以使用“协议省略”的URL允许单个脚本更灵活地引用内容。
接下来,我们继续简化加载本地脚本的代码,当jQuery成功加载到页面中,它会创建一个全局的jQuery变量,我们可以通过window的jQuery属性(window.jQuery)访问该变量的值,如果jQuery没有加载成功,那么window.jQuery就是未定义的。
所以,我们可以把代码简化成如下:
- <!-- Adds protocol-less google cdn reference -->
- <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
- <!--<script src="//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js"></script>-->
- <script>window.jQuery || document.write('<script src="js/jquery-2.0.0.min.js">\x3C/script>')</script>
上面,我们使用了“||”运算符判断window.jQuery是否为未定义类型,如果window.jQuery未定义执行后面的代码加载本地jQuery脚本,HTML5 Boilerplate就使用以上的方法处理CDN内容加载失败的情况。
Javascript加载器
有些人使用JavaScript加载器如:yepnope,它是一个能够根据输入条件来选择性异步加载资源文件的js脚本,可以在页面上仅加载用户需要的js或css,下面我们以加载jQuery为例子介绍yepnope的使用,具体实现如下:
- yepnope([{
- 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');
- }
- }
- }]);
上面,我们使用加载器yepnope把jQuery加载到页面中,接下来,我们介绍使用RequireJS加载jQuery,具体实现如下:
- // Uses requestJS to add cdn reference.
- requirejs.config({
- enforceDefine: true,
- paths: {
- jquery: [
- '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js',
- //If the CDN location fails, load from this location
- 'js/jquery-2.0.0.min'
- ]
- }
- });
- //Later
- require(['jquery'], function($) {
- // Your code here.
- });
我们可以RequireJS加载器中使用“协议省略”的URL地址,这样我们可以避免前面提到的加密协议和非加密协议加密和缓存问题了。
虽然,JS加载器也可以解决CDN内容加载失败的问题,但仅仅为了防止CDN内容加载失败问题而引入yepnope或RequireJS是没有必要的。
ASP.NET Web Form 4.5
对于每个ASP.NET Web窗体开发人员,我们需要了解在ASP.NET 4.5增加的新特性,其中就包含了处理CDN内容加载失败转移加载本地内容的特性。
首先,我们在页面中添加ScriptManager控件,然后设置该控制的EnableCdn属性为“True”,接着我们添加需要加载的内容名称,下面以加载jQuery为例:
- <!-- Set up cdn -->
- <asp:ScriptManager runat="server" EnableCdn="true">
- <Scripts>
- <asp:ScriptReference Name="jquery" />
- </Scripts>
- </asp:ScriptManager>
上面,我们通过ScriptManager控件指定加载jQuery库,但这里我们有一个疑问首先是我们没有指定加载jQuery库的URL地址,第二在加载失败后,没有指定本地jQuery库路径。
现在,我们通过运行页面代码查看ScriptManager生成的脚步代码,具体代码如下:
- <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.2.js" type="text/javascript"></script>
- <script type="text/javascript">
- //<![CDATA[
- (window.jQuery) || document.write('<script type="text/javascript" src="Scripts/jquery-1.8.2.js"><\/script>'); //]]>
- </script>
通过上面的代码,我们发现ScriptManager默认加载jQuery库的URL是http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.2.js,而且一旦加载失败它自动到Scripts文件中加载本地脚步。
虽然这种方式简单而且省心,但它默认是到微软的CDN中加载内容的,如果我们想使用Google的CDN呢?难道微软打算CDN也搞垄断吗?还有我们想使用jQuery 2.0.0库应该如何加载呢?
其实,我们可以通过自定义ScriptResourceMapping方式来指定加载的CDN和jQuery库,我们要在Global.asax 文件中添加以下代码:
- var mapping = ScriptManager.ScriptResourceMapping;
- // Map jquery definition to the Google CDN
- mapping.AddDefinition("jquery", new ScriptResourceDefinition
- {
- Path = "~/Scripts/jquery-2.0.0.min.js",
- DebugPath = "~/Scripts/jquery-2.0.0.js",
- CdnPath = "http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js",
- CdnDebugPath = "https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.js",
- CdnSupportsSecureConnection = true,
- LoadSuccessExpression = "window.jQuery"
- });
上面,我们定义了加载Google的CDN和jQuery 2.0.0版本,接下来我们重新运行页面代码查看ScriptManager生成的脚步代码是否对应我们的设置。
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.js" type="text/javascript"></script>
- <script type="text/javascript">
- //<![CDATA[
- (window.jQuery) || document.write('<script type="text/javascript" src="Scripts/jquery-2.0.0.js"><\/script>'); //]]>
- </script>
现在,我们看到使用的是Google的CDN,并且加载jQuery的版本为2.0.0的。
AspNet.ScriptManager.jQuery包
在ASP.NET4.5中,如果我们想使用jQuery 2.0.0或更新的版本,其实我们可以通过使用AspNet.ScriptManager.jQuery包来管理引用库的更新,其中它也包括配置CDN信息的功能,如果我们要获取最新的更新,首先我们选择工具->扩展工具管理器->AspNet.ScriptManager.jQuery,然后更新包就可以获取最新的jQuery库。
图2 AspNet.ScriptManager.jQuery包
ASP.NET Web Optimization包
如果我们使用的是ASP.NET MVC程序,同样我们可以通过更新ASP.NET Web Optimization包来管理CDN配置信息。
图3 ASP.NET Web Optimization包
接下来,我们在的BundleConfig中指定我们的CdnPath的URL地址,打开App_Start\BundleConfig.cs,我们可以看到里面有一个RegisterBundles()方法,下面是RegisterBundles()方法的一部分代码:
- /// <summary>
- /// Sets up the jquery libs load path.
- /// </summary>
- /// <param name="bundles"></param>
- public static void RegisterBundles(BundleCollection bundles)
- {
- bundles.UseCdn = true;
- BundleTable.EnableOptimizations = true; //force optimization while debugging
- var jquery = new ScriptBundle("~/bundles/jquery", "//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js").Include(
- "~/Scripts/jquery-{version}.js");
- jquery.CdnFallbackExpression = "window.jQuery";
- bundles.Add(jquery);
- //...
- }
1.1.3 总结
在本文中,我们向大家介绍了一些CDN内容引用失败的处理机制,就处理方式来说,我觉得HTML5 Boilerplate的解决方法不但简洁,而且不用引入第三方库。
同时我们也介绍了使用“协议省略”的CDN的优点,但有一点我们要注意的,如果我们在本地运行使用“协议省略”的URL可能不会得到如预期运行效果,由于我们在本地运行页面“协议省略”使用的基础协议是file,而不是http或https,所以一般来说我们在本地直接运行页面是无法正确获取到CDN的内容,我们可以把页面放到本地Web服务器中运行,如Apache或IIS中,然后运行http://localhost的地址就可以加载成功了。
参考
引用CDN内容的方法总结的更多相关文章
- 网站优化:引用CDN公共库
什么是CDN公共库? CDN公共库是指将常用的JS库存放在CDN节点,以方便广大开发者直接调用.与将JS库存放在服务器单机上相比,CDN公共库更加稳定.高速.一般的CDN公共库都会包含全球所有最流行的 ...
- HTML <!DOCTYPE> 标签 布局引用的几种方法 行级元素与块级元素
HTML <!DOCTYPE> 标签 <!DOCTYPE html> <html> <head> <title>文档的标题</titl ...
- 深入学习Python解析并解密PDF文件内容的方法
前面学习了解析PDF文档,并写入文档的知识,那篇文章的名字为深入学习Python解析并读取PDF文件内容的方法. 链接如下:https://www.cnblogs.com/wj-1314/p/9429 ...
- EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器解决方案之CDN内容分发网络
背景分析 EasyDSS流媒体解决方案提供一站式的转码.点播.直播.录像.检索.时移回放服务,极大地简化了开发和集成的工作,并且EasyDSS支持多种特性,完全能够满足企业视频信息化建设方面的需求.其 ...
- 在html页面引用css文件的方法
引用CSS文件到Html方法-css引入,css引用 使用不同的方法来引用css样式表,最终到达的效果相同,但是使用不同方法应用的css文件将影响到SEO及网页打开速度效率. html引用css方法如 ...
- linux几种快速清空文件内容的方法
linux几种快速清空文件内容的方法 几种快速清空文件内容的方法: $ : > filename #其中的 : 是一个占位符, 不产生任何输出. $ > filename $ echo & ...
- JavaScript动态改变表格单元格内容的方法
本文实例讲述了JavaScript动态改变表格单元格内容的方法.分享给大家供大家参考.具体如下: JavaScript动态改变表格单元格的内容,下面的代码通过修改单元格的innerHTML来修改单元格 ...
- shell中引用其他脚本的方法
在Shell中引用其他脚本的方法是source filename.sh 或 . filename.sh 注意: . 和 filename.sh之间必须有空格
- CDN 内容分发网络技术
1.前言 Internet的高速发展,给人们的工作和生活带来了极大的便利,对Internet的服务品质和访问速度要求越来越高,虽然带宽不断增加,用户数量也在不断增加,受Web服务器的负荷和传输距离等因 ...
随机推荐
- js页面的弹框怎么关闭啊
1.单纯的关闭window.opener.location.reload(); //刷新父窗口中的网页window.close();//关闭当前窗窗口2.提交后关闭 function save(){d ...
- java当拿到一个项目后该怎么看的一些个人见解(附带快捷键)
刚出来实习,BOSS让我用maven下载架包后进行修改. 刚开始拿到项目两眼一黑,完全不知道该怎么下手.想找server层,完全不知道在那么多架包那里开始弄. 这个时候首先要明确你要修改的位置,找到这 ...
- 关于不同数据库的连接配置(MySql和Oracle)
mysql: driverClass=com.mysql.jdbc.Driver #在和mysql传递数据的过程中,使用unicode编码格式,并且字符集设置为utf-8,插入数据库防止中文乱码 ur ...
- mysql下突然丢失权限
mysql Can't read dir of 今天打开mysql数据库突然报了这个错误 查后发现是表没权限,进行了mysql的data目录权限修改 1.show global variables ...
- Java基础知识(数据类型和集合)
一.数据类型 包装类型 包装类型是对基本数据类型不足之处的补充. 基本数据类型的传递方式是值传递,而包装类型是引用传递,同时提供了很多数据类型间转换的方法. Java1.5 以后可以自动装箱和拆箱 二 ...
- 新浪新闻API
新浪新闻API ustcmio 关注 2017.01.15 20:44* 字数 536 阅读 2479评论 2喜欢 7 新浪新闻的API:1.访问手机新浪网https://sina.cn/?from= ...
- html的常用标签详解1
1.<!DOCTYPE html> 文档声明,不算是标签,但是它可是不能少.这玩意是干什么用的呢? 它是向浏览器自报家门的,即告诉浏览器的解析器应该以什么样的文档类型定义(DTD)来解析它 ...
- LUOGU P4113 [HEOI2012]采花
传送门 解题思路 莫队题卡莫队...莫队只能拿到100分,满分200.正解主席树??发个莫队100分代码. 代码 #include<iostream> #include<cstdio ...
- Mysql--数据表碎片优化方法
碎片产生原因: 大量批量插入和删除操作数据库,基于线性表的顺序存储结构的特点,出现了大量的空间碎片.一.优化步骤: 1.查看整库的情况 2.方便优化 3.整库所有表, 包含行数 索引长度 碎片空间 二 ...
- Bootstrap.之模态框 显示在遮罩层后面
Bootstrap.之模态框 显示在遮罩层后面 问题描述: 在使用bootstrap模态框,弹出的窗口在遮罩层后面,见图: 解决方案: 保证模态框的代码,所在的上一级(父元素)是body标签,即可.例 ...