HttpCombiner也不记得是谁写的了,功能是把多个js文件或css文件合并到一块,压缩一下一起发给客户端来优化网站。用法是这样的: 但这样又不利于找错,所以在中间又加了一个方法,可随时控制是如上引用还是,如下一般引用: 修改后引用文件时:<%= HttpCombiner.Requires(true,"js","a.js", "b.js", "dialog/c.js", "dialog/d.js")%> 第一个参数来控制合并 。 一般处理程序cs源码:复制代码using System;using System.Web;using System.Net;using System.IO;using System.IO.Compression;using System.Text;using System.Web.Caching;public class HttpCombiner : IHttpHandler{ #region Config private const bool DO_GZIP = true; private readonly static TimeSpan CACHE_DURATION = TimeSpan.FromDays(30); private const string JSPathPre = "~/RES/JS/"; private const string CSSPathPre = "~/RES/CSS/"; private const string CombinerUrl = "/Part/Handle/HttpCombiner.ashx";//些handler路径 private const string JSAbsPathPre = "/RES/JS/"; private const string CSSAbsPathPre = "/RES/CSS/"; #endregion #region Requires 默认combin public static string Requires(bool combin, string type, params string[] files) { if (combin) { if (type == "js") { return string.Format("", CombinerUrl, string.Join(",", files)); } else if (type == "css") { return string.Format(" ", CombinerUrl, string.Join(",", files)); } else { return string.Empty; } } else { if (type == "js") { StringBuilder sb = new StringBuilder(); foreach (var file in files) { sb.AppendFormat("", JSAbsPathPre, file); sb.AppendLine(); } return sb.ToString(); } else if (type == "css") { StringBuilder sb = new StringBuilder(); foreach (var file in files) { sb.AppendFormat(" ", CSSAbsPathPre, file); sb.AppendLine(); } return sb.ToString(); } else { return string.Empty; } } } public static string Requires(string type, params string[] files) { return Requires(true, type, files); } #endregion #region Process public void ProcessRequest(HttpContext context) { HttpRequest request = context.Request; string setName = request["s"] ?? string.Empty; string contentType = request["t"] ?? string.Empty; if (string.IsNullOrEmpty(contentType)) { contentType = "type/javascript"; } else { if (contentType == "js") { contentType = "type/javascript"; } else if (contentType == "css") { contentType = "text/css"; } else { contentType = "text/plain"; } } bool isCompressed = DO_GZIP && CanGZip(context.Request); UTF8Encoding encoding = new UTF8Encoding(false); if (!WriteFromCache(context, setName, isCompressed, contentType)) { System.Collections.Generic.ListdependencyFiles = new System.Collections.Generic.List (); using (MemoryStream memoryStream = new MemoryStream(5000)) { using (Stream writer = isCompressed ? (Stream)(new GZipStream(memoryStream, CompressionMode.Compress)) : memoryStream) { string[] fileNames = setName.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string fileName in fileNames) { byte[] fileBytes = GetFileBytes(contentType, context, fileName.Trim(), encoding, dependencyFiles); writer.Write(fileBytes, 0, fileBytes.Length); } writer.Close(); } byte[] responseBytes = memoryStream.ToArray(); context.Cache.Insert(GetCacheKey(setName, isCompressed), responseBytes, new CacheDependency(dependencyFiles.ToArray()), System.Web.Caching.Cache.NoAbsoluteExpiration, CACHE_DURATION); WriteBytes(responseBytes, context, isCompressed, contentType); } } } private static byte[] GetFileBytes(string contentType, HttpContext context, string virtualPath, Encoding encoding, System.Collections.Generic.List depencesFile) { if (virtualPath.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase)) { using (WebClient client = new WebClient()) { return client.DownloadData(virtualPath); } } else { if (!virtualPath.StartsWith("~/", StringComparison.InvariantCultureIgnoreCase)) { if (contentType == "text/css") { virtualPath = CSSPathPre + virtualPath; } else if (contentType == "type/javascript") { virtualPath = JSPathPre + virtualPath; } } string physicalPath = context.Server.MapPath(virtualPath); depencesFile.Add(physicalPath); byte[] bytes = File.ReadAllBytes(physicalPath); return bytes; } } private static bool WriteFromCache(HttpContext context, string setName,bool isCompressed, string contentType) { byte[] responseBytes = context.Cache[GetCacheKey(setName, isCompressed)] as byte[]; if (null == responseBytes || 0 == responseBytes.Length) return false; WriteBytes(responseBytes, context, isCompressed, contentType); return true; } private static void WriteBytes(byte[] bytes, HttpContext context,bool isCompressed, string contentType) { HttpResponse response = context.Response; response.AppendHeader("Content-Length", bytes.Length.ToString()); response.ContentType = contentType; if (isCompressed) response.AppendHeader("Content-Encoding", "gzip"); context.Response.Cache.SetCacheability(HttpCacheability.Public); context.Response.Cache.SetExpires(DateTime.Now.Add(CACHE_DURATION)); context.Response.Cache.SetMaxAge(CACHE_DURATION); context.Response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate"); response.OutputStream.Write(bytes, 0, bytes.Length); response.Flush(); } private static bool CanGZip(HttpRequest request) { string acceptEncoding = request.Headers["Accept-Encoding"]; if (!string.IsNullOrEmpty(acceptEncoding) && (acceptEncoding.Contains("gzip") || acceptEncoding.Contains("deflate"))) return true; return false; } private static string GetCacheKey(string setName, bool isCompressed) { return "HttpCombiner." + setName + "." + isCompressed; } public bool IsReusable { get { return true; } } #endregion复制代码}