不知道大家有没有注意过google和baidu首页页面的html,打开一看你会发现,竟然没有缩排什么,几乎整个页面输出都快写成一行了,至于为什么这样做,我能想到的是节省流量,没别的想法了.那我们是不是也可以做到这样呢(虽然我们对流量没什么要求),当然是可以的,写代码的时候不要缩排,把html全部写在一行不就行了,当然这个方法的确可行,但是麻烦了点,而且维护起来也不方便.有没有更好的办法,当然是有,我们就利用HttpModule和Response.Filter来实现这个功能吧,废话说完了,切入正题.
既然是用HttpModule,那当然就得弄个实现了IHttpModule的类了:
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Web;5

6
namespace K2046.Handlers7
{8
public class FilterModule : IHttpModule9
{10
IHttpModule 成员31
}32
}在Web.Config的<system.web>中再加上如下代码:
<httpModules>2
<add name="ResponseFilter" type="K2046.Handlers.FilterModule, K2046.Handlers"/>3
</httpModules>在这里面用到了一个ResponseFilter的类,这个也是自己实现的,代码如下:
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.IO;5
using System.Text.RegularExpressions;6

7
namespace K2046.Handlers8
{9
public class ResponseFilter : Stream10
{11
private Stream _StreamFilter;12

13
private ResponseFilter() { }14

15
public ResponseFilter(Stream stream)16
{17
_StreamFilter = stream;18
}19

20
public override bool CanRead21
{22
get { return true; }23
}24

25
public override bool CanSeek26
{27
get { return true; }28
}29

30
public override bool CanWrite31
{32
get { return true; }33
}34

35
public override void Flush()36
{37
_StreamFilter.Flush();38
}39

40
public override long Length41
{42
get43
{44
return _StreamFilter.Length;45
}46
}47

48
public override long Position49
{50
get51
{52
return _StreamFilter.Position;53
}54
set55
{56
_StreamFilter.Position = value;57
}58
}59

60
public override int Read(byte[] buffer, int offset, int count)61
{62
return _StreamFilter.Read(buffer, offset, count);63
}64

65
public override long Seek(long offset, SeekOrigin origin)66
{67
return _StreamFilter.Seek(offset, origin);68
}69

70
public override void SetLength(long value)71
{72
_StreamFilter.SetLength(value);73
}74

75
public override void Write(byte[] buffer, int offset, int count)76
{77
string Html = Encoding.UTF8.GetString(buffer);78
Html = Regex.Replace(Html, @">\s+?<", "><");//去除Html中的空白字符.79
Html = Regex.Replace(Html, @"\r\n\s*", "");80
Html = Regex.Replace(Html, @"<body([\s|\S]*?)>([\s|\S]*?)</body>", @"<body$1>$2<!--Hello,Robot!--></body>", RegexOptions.IgnoreCase);81
buffer = Encoding.UTF8.GetBytes(Html);82
_StreamFilter.Write(buffer, offset, buffer.Length);83
}84
}85
}86

其实这个类没做什么,继承Stream,重写Write方法,就可以了,不过关键的就是这里了,在Write的时候,先把byte[]转成string,再把这个string按你想要的方式处理,你想把它整成什么样就整成什么样了.处理完了,再把string转成byte[],然后写入原来的stream里,就OK了.
我现在只是把一些空白字符去掉了,还可以干什么就看自己需要了.
注意:在FilterModule里,所有的请求都会被ResponseFilter处理,包括axd文件什么的,所以会造成输出有问题,所以在加ResponseFilter的时候自己要处理一下条件.
第一次发.NET的文章,写得不好请大家见谅,欢迎各位砖家指点.谢谢.
更新:其实记录这篇文章的原意是实现如何改写输出的流,没找到合适的东西,就用在压缩html上了,当然,也只是简单的去除了空白字符而已,重要的是实现在HttpModule里改写了输出的流.因为之前有碰到过这样的问题,找相关Response.Filter的资料也不多,有些也说得不是那么清楚,所以,做个笔记.

