Asp.net使用HttpModule压缩并删除空白Html请求

当我们压缩我的Response后再传到Client端时,可以明显节省宽带. 提升Site的性能. 现在的浏览器大部分都支持Gzip,Deflate压缩。同时我们还可以删除一些空白段、空行、注释等以使得HTML文档的尺寸变得更小. 让我们先来实现压缩与删除空白类, 继承自Stream类:。

当我们压缩我的Response后再传到Client端时,可以明显节省宽带. 提升Site的性能. 现在的浏览器大部分都支持Gzip,Deflate压缩。同时我们还可以删除一些空白段、空行、注释等以使得HTML文档的尺寸变得更小. 让我们先来实现压缩与删除空白类, 继承自Stream类:

  1. /// <summary> 
  2. /// CompressWhitespaceFilter 
  3. /// </summary> 
  4. public class CompressWhitespaceFilter : Stream 
  5. private GZipStream _contentGZipStream; 
  6. private DeflateStream _content_DeflateStream; 
  7. private Stream _contentStream; 
  8. private CompressOptions _compressOptions; 
  9. /// <summary> 
  10. /// Initializes a new instance of the <see cref="CompressWhitespaceFilter"/> class. 
  11. /// </summary> 
  12. /// <param name="contentStream">The content stream.</param> 
  13. /// <param name="compressOptions">The compress options.</param> 
  14. public CompressWhitespaceFilter(Stream contentStream, CompressOptions compressOptions) 
  15. if (compressOptions == CompressOptions.GZip) 
  16. this._contentGZipStream = new GZipStream(contentStream, CompressionMode.Compress); 
  17. this._contentStream = this._contentGZipStream; 
  18. else if (compressOptions == CompressOptions.Deflate) 
  19. this._content_DeflateStream = new DeflateStream(contentStream,CompressionMode.Compress); 
  20. this._contentStream = this._content_DeflateStream; 
  21. else 
  22. this._contentStream = contentStream; 
  23. this._compressOptions = compressOptions; 
  24. public override bool CanRead 
  25. get { return this._contentStream.CanRead; } 
  26. public override bool CanSeek 
  27. get { return this._contentStream.CanSeek; } 
  28. public override bool CanWrite 
  29. get { return this._contentStream.CanWrite; } 
  30. public override void Flush() 
  31. this._contentStream.Flush(); 
  32. public override long Length 
  33. get { return this._contentStream.Length; } 
  34. public override long Position 
  35. get 
  36. return this._contentStream.Position; 
  37. set 
  38. this._contentStream.Position = value; 
  39. public override int Read(byte[] buffer, int offset, int count) 
  40. return this._contentStream.Read(buffer, offset, count); 
  41. public override long Seek(long offset, SeekOrigin origin) 
  42. return this._contentStream.Seek(offset, origin); 
  43. public override void SetLength(long value) 
  44. this._contentStream.SetLength(value); 
  45. public override void Write(byte[] buffer, int offset, int count) 
  46. byte[] data = new byte[count + 1]; 
  47. Buffer.BlockCopy(buffer, offset, data, 0, count); 
  48. string strtext = System.Text.Encoding.UTF8.GetString(data); 
  49. strtext = Regex.Replace(strtext, "^\\s*", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline); 
  50. strtext = Regex.Replace(strtext, "\\r\\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline); 
  51. strtext = Regex.Replace(strtext, "<!--*.*?-->", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline); 
  52. byte[] outdata = System.Text.Encoding.UTF8.GetBytes(strtext); 
  53. this._contentStream.Write(outdata, 0, outdata.GetLength(0)); 
  54. /// <summary> 
  55. /// CompressOptions 
  56. /// </summary> 
  57. /// <seealso cref="http://en.wikipedia.org/wiki/Zcat#gunzip_and_zcat"/> 
  58. /// <seealso cref="http://en.wikipedia.org/wiki/DEFLATE"/> 
  59. public enum CompressOptions 
  60. GZip, 
  61. Deflate, 
  62. None 
  63. }
/// <summary> 
/// CompressWhitespaceFilter 
/// </summary> 
public class CompressWhitespaceFilter : Stream 
{ 
private GZipStream _contentGZipStream; 
private DeflateStream _content_DeflateStream; 
private Stream _contentStream; 
private CompressOptions _compressOptions; 
/// <summary> 
/// Initializes a new instance of the <see cref="CompressWhitespaceFilter"/> class. 
/// </summary> 
/// <param name="contentStream">The content stream.</param> 
/// <param name="compressOptions">The compress options.</param> 
public CompressWhitespaceFilter(Stream contentStream, CompressOptions compressOptions) 
{ 
if (compressOptions == CompressOptions.GZip) 
{ 
this._contentGZipStream = new GZipStream(contentStream, CompressionMode.Compress); 
this._contentStream = this._contentGZipStream; 
} 
else if (compressOptions == CompressOptions.Deflate) 
{ 
this._content_DeflateStream = new DeflateStream(contentStream,CompressionMode.Compress); 
this._contentStream = this._content_DeflateStream; 
} 
else 
{ 
this._contentStream = contentStream; 
} 
this._compressOptions = compressOptions; 
} 
public override bool CanRead 
{ 
get { return this._contentStream.CanRead; } 
} 
public override bool CanSeek 
{ 
get { return this._contentStream.CanSeek; } 
} 
public override bool CanWrite 
{ 
get { return this._contentStream.CanWrite; } 
} 
public override void Flush() 
{ 
this._contentStream.Flush(); 
} 
public override long Length 
{ 
get { return this._contentStream.Length; } 
} 
public override long Position 
{ 
get 
{ 
return this._contentStream.Position; 
} 
set 
{ 
this._contentStream.Position = value; 
} 
} 
public override int Read(byte[] buffer, int offset, int count) 
{ 
return this._contentStream.Read(buffer, offset, count); 
} 
public override long Seek(long offset, SeekOrigin origin) 
{ 
return this._contentStream.Seek(offset, origin); 
} 
public override void SetLength(long value) 
{ 
this._contentStream.SetLength(value); 
} 
public override void Write(byte[] buffer, int offset, int count) 
{ 
byte[] data = new byte[count + 1]; 
Buffer.BlockCopy(buffer, offset, data, 0, count); 
string strtext = System.Text.Encoding.UTF8.GetString(data); 
strtext = Regex.Replace(strtext, "^\\s*", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline); 
strtext = Regex.Replace(strtext, "\\r\\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline); 
strtext = Regex.Replace(strtext, "<!--*.*?-->", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline); 
byte[] outdata = System.Text.Encoding.UTF8.GetBytes(strtext); 
this._contentStream.Write(outdata, 0, outdata.GetLength(0)); 
} 
} 
/// <summary> 
/// CompressOptions 
/// </summary> 
/// <seealso cref="http://en.wikipedia.org/wiki/Zcat#gunzip_and_zcat"/> 
/// <seealso cref="http://en.wikipedia.org/wiki/DEFLATE"/> 
public enum CompressOptions 
{ 
GZip, 
Deflate, 
None 
} 

上面的代码使用正则表达式替换字符串,你可以修改那些正则表达式来满足你的需求. 我们同时使用了GZipStream与DeflateStream实现了压缩. 好的,接下来与HttpModule结合:

  1. /// <summary> 
  2. /// CompressWhitespaceModule 
  3. /// </summary> 
  4. public class CompressWhitespaceModule : IHttpModule 
  5. #region IHttpModule Members 
  6. /// <summary> 
  7. /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>. 
  8. /// </summary> 
  9. public void Dispose() 
  10. // Nothing to dispose; 
  11. /// <summary> 
  12. /// Initializes a module and prepares it to handle requests. 
  13. /// </summary> 
  14. /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param> 
  15. public void Init(HttpApplication context) 
  16. context.BeginRequest += new EventHandler(context_BeginRequest); 
  17. /// <summary> 
  18. /// Handles the BeginRequest event of the context control. 
  19. /// </summary> 
  20. /// <param name="sender">The source of the event.</param> 
  21. /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> 
  22. void context_BeginRequest(object sender, EventArgs e) 
  23. HttpApplication app = sender as HttpApplication; 
  24. if (app.Request.RawUrl.Contains(".aspx")) 
  25. HttpContext context = app.Context; 
  26. HttpRequest request = context.Request; 
  27. string acceptEncoding = request.Headers["Accept-Encoding"]; 
  28. HttpResponse response = context.Response; 
  29. if (!string.IsNullOrEmpty(acceptEncoding)) 
  30. acceptEncoding = acceptEncoding.ToUpperInvariant(); 
  31. if (acceptEncoding.Contains("GZIP")) 
  32. response.Filter = new CompressWhitespaceFilter(context.Response.Filter, CompressOptions.GZip); 
  33. response.AppendHeader("Content-encoding", "gzip"); 
  34. else if (acceptEncoding.Contains("DEFLATE")) 
  35. response.Filter = new CompressWhitespaceFilter(context.Response.Filter, CompressOptions.Deflate); 
  36. response.AppendHeader("Content-encoding", "deflate"); 
  37. response.Cache.VaryByHeaders["Accept-Encoding"] = true
  38. #endregion 
  39. }
/// <summary> 
/// CompressWhitespaceModule 
/// </summary> 
public class CompressWhitespaceModule : IHttpModule 
{ 
#region IHttpModule Members 
/// <summary> 
/// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>. 
/// </summary> 
public void Dispose() 
{ 
// Nothing to dispose; 
} 
/// <summary> 
/// Initializes a module and prepares it to handle requests. 
/// </summary> 
/// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param> 
public void Init(HttpApplication context) 
{ 
context.BeginRequest += new EventHandler(context_BeginRequest); 
} 
/// <summary> 
/// Handles the BeginRequest event of the context control. 
/// </summary> 
/// <param name="sender">The source of the event.</param> 
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> 
void context_BeginRequest(object sender, EventArgs e) 
{ 
HttpApplication app = sender as HttpApplication; 
if (app.Request.RawUrl.Contains(".aspx")) 
{ 
HttpContext context = app.Context; 
HttpRequest request = context.Request; 
string acceptEncoding = request.Headers["Accept-Encoding"]; 
HttpResponse response = context.Response; 
if (!string.IsNullOrEmpty(acceptEncoding)) 
{ 
acceptEncoding = acceptEncoding.ToUpperInvariant(); 
if (acceptEncoding.Contains("GZIP")) 
{ 
response.Filter = new CompressWhitespaceFilter(context.Response.Filter, CompressOptions.GZip); 
response.AppendHeader("Content-encoding", "gzip"); 
} 
else if (acceptEncoding.Contains("DEFLATE")) 
{ 
response.Filter = new CompressWhitespaceFilter(context.Response.Filter, CompressOptions.Deflate); 
response.AppendHeader("Content-encoding", "deflate"); 
} 
} 
response.Cache.VaryByHeaders["Accept-Encoding"] = true; 
} 
} 
#endregion 
} 

HttpApplication.BeginRequest 事件是 在 ASP.NET 响应请求时作为 HTTP 执行管线链中的第一个事件发生。 在WEB.CONFIG中你还需要配置:

  1. <httpModules> 
  2. <add name="CompressWhitespaceModule" type="MyWeb.CompressWhitespaceModule" /> 
  3. </httpModules>
<httpModules> 
<add name="CompressWhitespaceModule" type="MyWeb.CompressWhitespaceModule" /> 
</httpModules> 

我们来看一下效果。 没有使用压缩时为4.8K

没有使用压缩时为4.8K

使用压缩后,为1.6K

使用压缩后,为1.6K

很简单,你可以按需求来增加更多的功能. 希望对您开发有帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值