压缩 html 可以去除代码中无用的空格等,这样可提高网站的加载速度并节省带宽。
实现 ActionFilter 来完成 html 的压缩
public class WhitespaceFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var request = filterContext.HttpContext.Request; var response = filterContext.HttpContext.Response; response.Filter = new WhiteSpaceFilter(response.Filter, s => { s = Regex.Replace(s, @"s+(?=<)|s+$|(?<=>)s+", ""); //single-line doctype must be preserved var firstEndBracketPosition = s.IndexOf(">"); if (firstEndBracketPosition >= 0) { s = s.Remove(firstEndBracketPosition, 1); s = s.Insert(firstEndBracketPosition, ">"); } return s; }); } }
使用时在 Action 方法上添加 Filter 属性即可,如下:
[WhitespaceFilter] public ActionResult Index(string id) { return View(); }
我主要修改了下作者使用的正则,因为原正则会将<pre></pre>中的空格也进行替换,并指定编码为 UTF-8。
使用 Gzip 压缩
/// <summary> /// gzip /// [Compress] ///public ActionResult Index(string id) ///{ /// return View(); ///} /// </summary> public class CompressAttribute : ActionFilterAttribute { public override void OnResultExecuted(ResultExecutedContext filterContext) { var acceptEncoding = filterContext.HttpContext.Request.Headers["Accept-Encoding"]; if (!string.IsNullOrEmpty(acceptEncoding)) { acceptEncoding = acceptEncoding.ToLower(); var response = filterContext.HttpContext.Response; if (acceptEncoding.Contains("gzip")) { response.AppendHeader("Content-encoding", "gzip"); response.Filter = new GZipStream(response.Filter, CompressionMode.Compress); } else if (acceptEncoding.Contains("deflate")) { response.AppendHeader("Content-encoding", "deflate"); response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress); } } } } /// <summary> /// 压缩 HTML /// [WhitespaceFilter] ///public ActionResult Index(string id) ///{ /// return View(); ///} /// </summary> public class WhitespaceFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var request = filterContext.HttpContext.Request; var response = filterContext.HttpContext.Response; response.Filter = new WhiteSpaceFilter(response.Filter, s => { s = Regex.Replace(s, @"s+(?=<)|s+$|(?<=>)s+", ""); //single-line doctype must be preserved var firstEndBracketPosition = s.IndexOf(">"); if (firstEndBracketPosition >= 0) { s = s.Remove(firstEndBracketPosition, 1); s = s.Insert(firstEndBracketPosition, ">"); } return s; }); } } public class WhiteSpaceFilter : Stream { private Stream _shrink; private Func<string, string> _filter; public WhiteSpaceFilter(Stream shrink, Func<string, string> filter) { _shrink = shrink; _filter = filter; } public override bool CanRead { get { return true; } } public override bool CanSeek { get { return true; } } public override bool CanWrite { get { return true; } } public override void Flush() { _shrink.Flush(); } public override long Length { get { return 0; } } public override long Position { get; set; } public override int Read(byte[] buffer, int offset, int count) { return _shrink.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return _shrink.Seek(offset, origin); } public override void SetLength(long value) { _shrink.SetLength(value); } public override void Close() { _shrink.Close(); } public override void Write(byte[] buffer, int offset, int count) { // capture the data and convert to string byte[] data = new byte[count]; Buffer.BlockCopy(buffer, offset, data, 0, count); string s = Encoding.UTF8.GetString(buffer); // filter the string s = _filter(s); // write the data to stream byte[] outdata = Encoding.UTF8.GetBytes(s); _shrink.Write(outdata, 0, outdata.GetLength(0)); } }
这样当这个Action发生请求的时候返回到客户端的数据页面就会有明显的压缩效果了。
那么如果在我们的程序中每个Action都需要进行压缩处理的话,每个Action都要这样加,感觉很麻烦。所以这里我们可以这样来处理
[Compress] public class BaseController : Controller { }
定义一个基类Controller,然后之后的所有控制器都进行继承,那么基类Controller的属性也会继承。
public class HomeController : BaseController { public ActionResult Index() { ViewBag.Message = "Welcome to ASP.NET MVC!"; return View(); } public ActionResult About() { return View(); } }