ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler,

使用<link type="text/css" rel="Stylesheet" href="HttpCombiner.ashx?" />,具体的参数请参考程序中的介绍。

using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Services;
 
namespace SLTech.DST.Web.Application
{
    /// <summary>
    /// Summary description for $codebehindclassname$
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class HttpCombiner : IHttpHandler
    {
        private const bool DO_GZIP = true;
        private readonly static TimeSpan CACHE_DURATION = TimeSpan.FromDays(30);
        private const string DEFAULT_CSS = "decision-support-toolkit.css,controls/tab.css,controls/extension-button.css,";
 
        public void ProcessRequest(HttpContext context)
        {
            var request = context.Request;
 
            // Read setName, contentType and version.
            //All are required. They are used as cache key
            var setName = request["s"] ?? string.Empty;
            var contentType = request["t"] ?? string.Empty;
            var version = request["v"] ?? string.Empty;
            var files = request["f"] ?? string.Empty;
            files = DEFAULT_CSS + files;
 
            // Decide if browser supports compressed response
            var isCompressed = DO_GZIP && this.CanGZip(context.Request);
 
            // Response is written as UTF8 encoding.
            var encoding = new UTF8Encoding(false);
 
            // If the set has already been cached, write the response directly from
            // cache. Otherwise generate the response and cache it
            if (!this.WriteFromCache(context, setName, version, isCompressed, contentType))
            {
                using (var memoryStream = new MemoryStream(5000))
                {
                    // Decide regular stream or GZipStream based on whether the response
                    // can be cached or not
                    using (var writer = isCompressed ?
                        (Stream)(new GZipStream(memoryStream, CompressionMode.Compress)) :
                        memoryStream)
                    {
                        // Load the files defined and process each file
                        var fileNames = files.Split(new char[] { ',' },
                            StringSplitOptions.RemoveEmptyEntries);
 
                        foreach (string fileName in fileNames)
                        {
                            var fileBytes = this.GetFileBytes(context,"css/"+fileName.Trim(), encoding);
                            writer.Write(fileBytes, 0, fileBytes.Length);
                        }
 
                        writer.Close();
                    }
 
                    var responseBytes = memoryStream.ToArray();
                    context.Cache.Insert(GetCacheKey(setName, version, isCompressed),
                        responseBytes, null, System.Web.Caching.Cache.NoAbsoluteExpiration,
                        CACHE_DURATION);
 
                    // Generate the response
                    this.WriteBytes(responseBytes, context, isCompressed, contentType);
                }
            }
        }
 
        private byte[] GetFileBytes(HttpContext context, string virtualPath, Encoding encoding)
        {
            if (virtualPath.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
            {
                using (var client = new WebClient())
                {
                    return client.DownloadData(virtualPath);
                }
            }
            else
            {
                var physicalPath = context.Server.MapPath(virtualPath);
                var bytes = File.ReadAllBytes(physicalPath);
                return bytes;
            }
        }
 
        private bool WriteFromCache(HttpContext context, string setName, string version,
            bool isCompressed, string contentType)
        {
            var responseBytes = context.Cache[GetCacheKey(setName, version, isCompressed)] as byte[];
 
            if (null == responseBytes || 0 == responseBytes.Length) return false;
 
            this.WriteBytes(responseBytes, context, isCompressed, contentType);
            return true;
        }
 
        private void WriteBytes(byte[] bytes, HttpContext context,
            bool isCompressed, string contentType)
        {
            var 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 bool CanGZip(HttpRequest request)
        {
            var acceptEncoding = request.Headers["Accept-Encoding"];
            return (!string.IsNullOrEmpty(acceptEncoding) &&
                    (acceptEncoding.Contains("gzip") || acceptEncoding.Contains("deflate")));
        }
 
        private string GetCacheKey(string setName, string version, bool isCompressed)
        {
            return "HttpCombiner." + setName + "." + version + "." + isCompressed;
        }
 
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

 参照:http://www.cnblogs.com/sntetwt/p/3375586.html

 posted on 2017-12-01 11:28  dianli  阅读(233)  评论(0编辑  收藏  举报