• 用HttpCombiner来减少js和css的请问次数


    HttpCombiner也不记得是谁写的了,功能是把多个js文件或css文件合并到一块,压缩一下一起发给客户端来优化网站。
    用法是这样的:
    
     
    
    <script type="text/javascript" src="/Part/Handle/HttpCombiner.ashx?t=js&s=a.js,b.js,dialog/c.js,dialog/d.js"></script> 
     
    
      但这样又不利于找错,所以在中间又加了一个方法,可随时控制是如上引用还是,如下一般引用:
    
    <script type="text/javascript" src="/RES/JS/a.js"></script>
    <script type="text/javascript" src="/RES/JS/b.js"></script>
    <script type="text/javascript" src="/RES/JS/dialog/c.js"></script>
    <script type="text/javascript" src="/RES/JS/dialog/d.js"></script>
     
    
     修改后引用文件时:
    
    <%= 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("<script type="text/javascript" src="{0}?t=js&s={1}"></script>", CombinerUrl, string.Join(",", files));
                }
                else if (type == "css")
                {
                    return string.Format("<link rel="stylesheet" type="text/css" href="{0}?t=css&s={1}"  />", CombinerUrl, string.Join(",", files));
                }
                else
                {
                    return string.Empty;
                }
            }
            else
            {
                if (type == "js")
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (var file in files)
                    {
                        sb.AppendFormat("<script type="text/javascript" src="{0}{1}"></script>", JSAbsPathPre, file);
                        sb.AppendLine();
                    }
                    return sb.ToString();
                }
                else if (type == "css")
                {
                    StringBuilder sb = new StringBuilder();
                    foreach (var file in files)
                    {
                        sb.AppendFormat("<link rel="stylesheet" type="text/css" href="{0}{1}" />", 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.List<string> dependencyFiles = new System.Collections.Generic.List<string>();
                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<string> 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
    复制代码
    } 
  • 相关阅读:
    POJ3171 线段树优化dp
    Codeforces Round #590 (Div. 3)
    POJ2777 线段树区间染色问题
    POJ2182 Lost Cows 树状数组,二分
    P1908 逆序对 树状数组
    2019 Multi-University Training Contest 3
    主席树板子题区间第k小
    权值线段树板子题
    KMP板子题
    稀疏贝叶斯
  • 原文地址:https://www.cnblogs.com/jordan2009/p/4858932.html
Copyright © 2020-2023  润新知