zoukankan      html  css  js  c++  java
  • ASP.NET 打包多CSS或JS文件以加快页面加载速度的Handler

    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;
                }
            }
        }
    }
    
  • 相关阅读:
    Nginx+IIS+Redis 处理Session共享问题 2
    Nginx+IIS+Redis 处理Session共享问题 1
    [ZooKeeper.net] 1 模仿dubbo实现一个简要的http服务的注册 基于webapi
    使用小技巧使子功能模块不污染主框架
    sqlserver 去除重复的行数据
    setsockopt用法详解
    windows 非窗口定时器
    Redis list 之增删改查
    王垠:如何掌握程序语言(转)
    【练习】整树转换为16进制的字符串的函数
  • 原文地址:https://www.cnblogs.com/sntetwt/p/3375586.html
Copyright © 2011-2022 走看看