目标
实现对Web请求的动态内容进行字符串过滤,比如去掉所有注释和空行(可自行配置),亦可压缩HTML输出流,减小流量消耗。
前言
关于什么是HttpModule及其作用,可自行查找相关文章。本文旨在通过对HttpModule的实际应用,加深对服务器动态处理请求过程的理解。其中参考了网上几位大侠的处理思路,同时结合自身实际,编织出了自己的一套方法。当然肯定有更适合的处理办法,希望有缘能看到这篇文章的朋友们不吝赐教,并且对于其中的不当之处,如能指出,感激不尽。
创建HttpModule
- 开始第一步,向项目中添加一个新类HttpFilterModule,实现IHttpModule类的接口,命名为HttpFilterModule.cs,默认位于App_Code文件夹中。
- 在IHttpModule中需要实现两个接口函数,一个是Init(HttpApplication application),其中以HttpApplication类型作为传入参数,需要具体实现,也是主要实现方法;一个是Dispose(),无参数,这里无需具体实现方法。HttpFilterModule.cs文件内容如下:
using System;
using System.Web;
using System.Web.Configuration;
///
/// HTTP页面字符串过滤
///
public class HttpFilterModule : IHttpModule
{
public HttpFilterModule(){}
public void Init(HttpApplication application)
{
//TODO: 这里实现具体过滤方法
}
public void Dispose() { }
}
主要HttpModule建立好了,现在需要的是实现方法。不过现在涉及到另一个很重要的对象:Response.Filter,通过IntelliSense的快速信息我们可以看到,Response.Filter对象属于System.IO.Stream对象,解释是“获取或设置一个包装筛选器对象,该对象用于在传输之前修改HTTP实体主体。”因此可以看出通过修改(设置)改对象可达到过滤HTTP实体主体内容的目的。
创建RawFilter过滤器
既然Response.Filter对象属于System.IO.Stream对象,要修改它就需要建立一个原始过滤对象,继承Stream对象,然后重写Stream对象的Write()方法修改其输出对象,最后将重写后的Stream流对象赋给Response.Filter对象即可。具体操作:新建
RawFilter.cs文件,默认也位于App_Code文件夹中,双击打开输入以下代码:
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml.XPath;
///
/// 自定义原始过滤器,用于处理原始数据流
///
public class RawFilter : Stream
{
Stream responseStream;
HttpRequest request;
long position;
StringBuilder responseHtml;
///
/// 原始过滤器
///
/// 输入流
public RawFilter(Stream inputStream, HttpRequest httpRequest)
{
responseStream = inputStream;
responseHtml = new StringBuilder();
request = httpRequest;
}
//关键的点,在HttpResponse 输出内容的时候,输出一定会调用此方法数据,所以要在此方法内截获数据(重写)
public override void Write(byte[] buffer, int offset, int count)
{
string strBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
//采用正则表达式,检查输入是否有页面结束符