1. HttpCombiner也不记得是谁写的了,功能是把多个js文件或css文件合并到一块,压缩一下一起发给客户端来优化网站。
  2. 用法是这样的:
  3.  
  4. <script type="text/javascript" src="/Part/Handle/HttpCombiner.ashx?t=js&s=a.js,b.js,dialog/c.js,dialog/d.js"></script>
  5.  
  6. 但这样又不利于找错,所以在中间又加了一个方法,可随时控制是如上引用还是,如下一般引用:
  7.  
  8. <script type="text/javascript" src="/RES/JS/a.js"></script>
  9. <script type="text/javascript" src="/RES/JS/b.js"></script>
  10. <script type="text/javascript" src="/RES/JS/dialog/c.js"></script>
  11. <script type="text/javascript" src="/RES/JS/dialog/d.js"></script>
  12.  
  13. 修改后引用文件时:
  14.  
  15. <%= HttpCombiner.Requires(true,"js","a.js", "b.js", "dialog/c.js", "dialog/d.js")%>
  16.  
  17. 第一个参数来控制合并
  18.  
  19. 一般处理程序cs源码:
  20.  
  21. 复制代码
  22. using System;
  23. using System.Web;
  24. using System.Net;
  25. using System.IO;
  26. using System.IO.Compression;
  27. using System.Text;
  28. using System.Web.Caching;
  29.  
  30. public class HttpCombiner : IHttpHandler
  31. {
  32. #region Config
  33. private const bool DO_GZIP = true;
  34. private readonly static TimeSpan CACHE_DURATION = TimeSpan.FromDays();
  35. private const string JSPathPre = "~/RES/JS/";
  36. private const string CSSPathPre = "~/RES/CSS/";
  37. private const string CombinerUrl = "/Part/Handle/HttpCombiner.ashx";//些handler路径
  38.  
  39. private const string JSAbsPathPre = "/RES/JS/";
  40. private const string CSSAbsPathPre = "/RES/CSS/";
  41. #endregion
  42.  
  43. #region Requires 默认combin
  44. public static string Requires(bool combin, string type, params string[] files)
  45. {
  46. if (combin)
  47. {
  48. if (type == "js")
  49. {
  50. return string.Format("<script type=\"text/javascript\" src=\"{0}?t=js&s={1}\"></script>", CombinerUrl, string.Join(",", files));
  51. }
  52. else if (type == "css")
  53. {
  54. return string.Format("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}?t=css&s={1}\" />", CombinerUrl, string.Join(",", files));
  55. }
  56. else
  57. {
  58. return string.Empty;
  59. }
  60. }
  61. else
  62. {
  63. if (type == "js")
  64. {
  65. StringBuilder sb = new StringBuilder();
  66. foreach (var file in files)
  67. {
  68. sb.AppendFormat("<script type=\"text/javascript\" src=\"{0}{1}\"></script>", JSAbsPathPre, file);
  69. sb.AppendLine();
  70. }
  71. return sb.ToString();
  72. }
  73. else if (type == "css")
  74. {
  75. StringBuilder sb = new StringBuilder();
  76. foreach (var file in files)
  77. {
  78. sb.AppendFormat("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}{1}\" />", CSSAbsPathPre, file);
  79. sb.AppendLine();
  80. }
  81. return sb.ToString();
  82. }
  83. else
  84. {
  85. return string.Empty;
  86. }
  87. }
  88. }
  89. public static string Requires(string type, params string[] files)
  90. {
  91. return Requires(true, type, files);
  92. }
  93. #endregion
  94.  
  95. #region Process
  96. public void ProcessRequest(HttpContext context)
  97. {
  98.  
  99. HttpRequest request = context.Request;
  100.  
  101. string setName = request["s"] ?? string.Empty;
  102. string contentType = request["t"] ?? string.Empty;
  103. if (string.IsNullOrEmpty(contentType))
  104. {
  105. contentType = "type/javascript";
  106. }
  107. else
  108. {
  109. if (contentType == "js")
  110. {
  111. contentType = "type/javascript";
  112. }
  113. else if (contentType == "css")
  114. {
  115. contentType = "text/css";
  116. }
  117. else
  118. {
  119. contentType = "text/plain";
  120. }
  121. }
  122. bool isCompressed = DO_GZIP && CanGZip(context.Request);
  123.  
  124. UTF8Encoding encoding = new UTF8Encoding(false);
  125.  
  126. if (!WriteFromCache(context, setName, isCompressed, contentType))
  127. {
  128. System.Collections.Generic.List<string> dependencyFiles = new System.Collections.Generic.List<string>();
  129. using (MemoryStream memoryStream = new MemoryStream())
  130. {
  131. using (Stream writer = isCompressed ?
  132. (Stream)(new GZipStream(memoryStream, CompressionMode.Compress)) :
  133. memoryStream)
  134. {
  135. string[] fileNames = setName.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  136. foreach (string fileName in fileNames)
  137. {
  138. byte[] fileBytes = GetFileBytes(contentType, context, fileName.Trim(), encoding, dependencyFiles);
  139. writer.Write(fileBytes, , fileBytes.Length);
  140. }
  141. writer.Close();
  142. }
  143. byte[] responseBytes = memoryStream.ToArray();
  144. context.Cache.Insert(GetCacheKey(setName, isCompressed), responseBytes, new CacheDependency(dependencyFiles.ToArray()), System.Web.Caching.Cache.NoAbsoluteExpiration, CACHE_DURATION);
  145. WriteBytes(responseBytes, context, isCompressed, contentType);
  146. }
  147. }
  148. }
  149.  
  150. private static byte[] GetFileBytes(string contentType, HttpContext context, string virtualPath, Encoding encoding, System.Collections.Generic.List<string> depencesFile)
  151. {
  152. if (virtualPath.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
  153. {
  154. using (WebClient client = new WebClient())
  155. {
  156. return client.DownloadData(virtualPath);
  157. }
  158. }
  159. else
  160. {
  161. if (!virtualPath.StartsWith("~/", StringComparison.InvariantCultureIgnoreCase))
  162. {
  163. if (contentType == "text/css")
  164. {
  165. virtualPath = CSSPathPre + virtualPath;
  166. }
  167. else if (contentType == "type/javascript")
  168. {
  169. virtualPath = JSPathPre + virtualPath;
  170. }
  171. }
  172. string physicalPath = context.Server.MapPath(virtualPath);
  173. depencesFile.Add(physicalPath);
  174. byte[] bytes = File.ReadAllBytes(physicalPath);
  175. return bytes;
  176. }
  177. }
  178.  
  179. private static bool WriteFromCache(HttpContext context, string setName,bool isCompressed, string contentType)
  180. {
  181. byte[] responseBytes = context.Cache[GetCacheKey(setName, isCompressed)] as byte[];
  182. if (null == responseBytes || == responseBytes.Length) return false;
  183. WriteBytes(responseBytes, context, isCompressed, contentType);
  184. return true;
  185. }
  186.  
  187. private static void WriteBytes(byte[] bytes, HttpContext context,bool isCompressed, string contentType)
  188. {
  189. HttpResponse response = context.Response;
  190. response.AppendHeader("Content-Length", bytes.Length.ToString());
  191. response.ContentType = contentType;
  192. if (isCompressed) response.AppendHeader("Content-Encoding", "gzip");
  193. context.Response.Cache.SetCacheability(HttpCacheability.Public);
  194. context.Response.Cache.SetExpires(DateTime.Now.Add(CACHE_DURATION));
  195. context.Response.Cache.SetMaxAge(CACHE_DURATION);
  196. context.Response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
  197. response.OutputStream.Write(bytes, , bytes.Length);
  198. response.Flush();
  199. }
  200.  
  201. private static bool CanGZip(HttpRequest request)
  202. {
  203. string acceptEncoding = request.Headers["Accept-Encoding"];
  204. if (!string.IsNullOrEmpty(acceptEncoding) && (acceptEncoding.Contains("gzip") || acceptEncoding.Contains("deflate")))
  205. return true;
  206. return false;
  207. }
  208.  
  209. private static string GetCacheKey(string setName, bool isCompressed)
  210. {
  211. return "HttpCombiner." + setName + "." + isCompressed;
  212. }
  213.  
  214. public bool IsReusable
  215. {
  216. get
  217. {
  218. return true;
  219. }
  220. }
  221. #endregion
  222. 复制代码
  223. }

用HttpCombiner来减少js和css的请问次数的更多相关文章

  1. Web性能优化-合并js与css,减少请求

    Web性能优化已经是老生常谈的话题了, 不过笔者也一直没放在心上,主要的原因还是项目的用户量以及页面中的js,css文件就那几个,感觉没什么优化的.人总要进步的嘛,最近在被angularjs吸引着,也 ...

  2. IE和firefox火狐在JS、css兼容区别

    1.firefox不能对innerText支持. firefox支持innerHTML但却不支持innerText,它支持textContent来实现innerText,不过默认把多余的空格也保留了. ...

  3. [转][前端优化]使用Combres合并对js、css文件的请求

    本文转自:http://www.cnblogs.com/parry/archive/2011/01/28/Reduce_Http_Request_Using_Combres_For_Js_Css.ht ...

  4. 将Microsoft Ajax Minifier集成到VS2013对JS、CSS进行编译时压缩

    在网站发布中,一般要将js,css文件压缩减少体积,以减少在HTTP请求中的流量.将Microsoft Ajax Minifier集成到VS2013中就可以对JS.CSS进行编译时压缩. VS2013 ...

  5. MVC中的JS和CSS压缩

    小说一下Js和CSS压缩的好处: 1.减小了文件的体积 2.减小了网络传输量和带宽占用 3.减小了服务器的处理的压力 4.提高了页面的渲染显示的速度  很多建议将站点的静态文件(如图片.js.css ...

  6. 为js和css文件自动添加版本号

    web应用必然要面对缓存问题,无论前台后台都会涉足缓存.特别是对于前端而言,缓存利用的是否得当直接关系到应用的性能. 通常情况下,我们会倾向于使用缓存,因为缓存一方面可以减少网络开销,一方面可以减轻服 ...

  7. nginx js、css多个请求合并为一个请求(concat模块)

    模块介绍 mod_concat模块由淘宝开发,目前已经包含在tengine中,并且淘宝已经在使用这个nginx模块.不过塔暂时没有包含在nginx中.这个模块类似于apache中的modconcat. ...

  8. PHP中,JS和CSS优化工具Minify的使用方法

    为减少HTTP请求,我们往往需要合并和压缩多个JS和CSS文件,下面记录下网上关于实现这个功能的PHP源码以及开源项目Minify的使用方法 一.实现合并和压缩多个JS和CSS文件的代码请参考 1.一 ...

  9. 经验总结:按需加载JS和css

    项目中做过这样的事情:所有页面都通过SSI指令 include这样一份public-js.shtml, 用来引入涉及到的js(包括公共的脚本 验证插件 自定义组件等),但是一些没有交互效果的页面根本不 ...

随机推荐

  1. Java中的overload(方法的覆写)

    方法覆写(overload)与方法的重载非常相似,它在 Java的继承中也有很重要的应用. 写程序可能会碰到下面的情况,在父类中已经实现的方法可能不够精确,不能满足子类 的需求.例如在前面的 Anim ...

  2. 新人浅谈__(数据库的设计__数据库模型图,数据库E-R图,三大范式)

    >>>>  为什么需要规范的数据库设计 在实际的项目开发中,如果系统的数据存储量较大,设计的表比较多,表和表之间的关系比较复杂,就需要首先考虑规范的数据库设计,然后进行创建库, ...

  3. 使用Kettle增量抽取MongoDB数据实践

    需求: 增量抽取MongoDB数据并加载到MSSQL 由于不能使用关系型数据库的自定义SQL, 所以主要遇到的问题有: 增量时间的查询和参数控制 ETL的批次信息和调用参数的写入 第一个问题的解决如下 ...

  4. 移动web——bootstrap媒体对象

    基本模板 1.这些组件都具有在文本内容的左或右侧对齐的图片(就像博客评论或 Twitter 消息等) <div class="media"> <div class ...

  5. JS——事件冒泡与捕获

    事件冒泡与事件捕获 1.冒泡:addEventListener("click",fn,false)或者addEventListener("click",fn): ...

  6. JAVA趣味逻辑算法

    /**已知4位同学中的一位数学考了100分,当小李询问这4位是谁考了100分时,4个人的回答如下: A说:不是我. B说:是C C说:是D. D说:他胡说. 已知三个人说的是真话,一个人说的是假话.现 ...

  7. select2下拉插件

    下拉单选: 1.行内 1)初始化数据: <select class="form-control select5"> <option selected>张三1 ...

  8. python socket 接口

    一.简介 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求.socket起 ...

  9. js的三种对象

    JS中,可以将对象分为“内部对象”.“宿主对象”和“自定义对象”三种. 1,内部对象 js中的内部对象包括Array.Boolean.Date.Function.Global.Math.Number. ...

  10. Java中“==”、“compareTo()”和“equals()”的区别

    在比较两个对象或者数据大小的时候,经常会用到==.compareTo()和equals(),尤其是在接入了Comparable接口后重写compareTo方法等场景,所以我们来理一下这三个的区别. 1 ...