1. 程式人生 > >利用HttpModule和ResponseFilter來壓縮你的html

利用HttpModule和ResponseFilter來壓縮你的html

 不知道大家有沒有注意過google和baidu首頁頁面的html,開啟一看你會發現,竟然沒有縮排什麼,幾乎整個頁面輸出都快寫成一行了,至於為什麼這樣做,我能想到的是節省流量,沒別的想法了.那我們是不是也可以做到這樣呢(雖然我們對流量沒什麼要求),當然是可以的,寫程式碼的時候不要縮排,把html全部寫在一行不就行了,當然這個方法的確可行,但是麻煩了點,而且維護起來也不方便.有沒有更好的辦法,當然是有,我們就利用HttpModule和Response.Filter來實現這個功能吧,廢話說完了,切入正題.

  既然是用HttpModule,那當然就得弄個實現了IHttpModule的類了:

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.Web;
 5
 6namespace K2046.Handlers
 7ExpandedBlockStart.gif{
 8    publicclass FilterModule : IHttpModule
 9ExpandedSubBlockStart.gif    {
10ExpandedSubBlockStart.gif        #region IHttpModule 成員11
12        publicvoid Dispose()
13ExpandedSubBlockStart.gif        
{
14            // Do Nothing.15        }
16
17        publicvoid Init(HttpApplication context)
18ExpandedSubBlockStart.gif        {
19            context.BeginRequest +=new EventHandler(Application_BeginRequest);
20        }
21
22        void Application_BeginRequest(object sender, EventArgs e)
23ExpandedSubBlockStart.gif        {
24            HttpApplication app 
= sender as HttpApplication;
25            if (true)//這裡看情況加上你的條件,要不然所有的請求都會被處理,會造成其它檔案型別的輸出異常.26ExpandedSubBlockStart.gif{
27                app.Response.Filter =new ResponseFilter(app.Response.Filter);
28            }
29        }
30        #endregion
31    }
32}

  在Web.Config的<system.web>中再加上如下程式碼:

1<httpModules>2            
<add name="ResponseFilter" type="K2046.Handlers.FilterModule, K2046.Handlers"/>3        </httpModules>

  在這裡面用到了一個ResponseFilter的類,這個也是自己實現的,程式碼如下:

 1using System;
 2using System.Collections.Generic;
 3using System.Text;
 4using System.IO;
 5using System.Text.RegularExpressions;
 6
 7namespace K2046.Handlers
 8ExpandedBlockStart.gif{
 9    publicclass ResponseFilter : Stream
10ExpandedSubBlockStart.gif    {
11        private Stream _StreamFilter;
12
13ExpandedSubBlockStart.gif        private ResponseFilter() { }14
15        public ResponseFilter(Stream stream)
16ExpandedSubBlockStart.gif        {
17            _StreamFilter = stream;
18        }
19
20        publicoverridebool CanRead
21ExpandedSubBlockStart.gif        {
22ExpandedSubBlockStart.gif            getreturntrue; }23        }
24
25        publicoverridebool CanSeek
26ExpandedSubBlockStart.gif        {
27ExpandedSubBlockStart.gif            getreturntrue; }28        }
29
30        publicoverridebool CanWrite
31ExpandedSubBlockStart.gif        {
32ExpandedSubBlockStart.gif            getreturntrue; }33        }
34
35        publicoverridevoid Flush()
36ExpandedSubBlockStart.gif        {
37            _StreamFilter.Flush();
38        }
39
40        publicoverridelong Length
41ExpandedSubBlockStart.gif        {
42            get43ExpandedSubBlockStart.gif            {
44                return _StreamFilter.Length;
45            }
46        }
47
48        publicoverridelong Position
49ExpandedSubBlockStart.gif        {
50            get51ExpandedSubBlockStart.gif            {
52                return _StreamFilter.Position;
53            }
54            set55ExpandedSubBlockStart.gif            {
56                _StreamFilter.Position = value;
57            }
58        }
59
60        publicoverrideint Read(byte[] buffer, int offset, int count)
61ExpandedSubBlockStart.gif        {
62            return _StreamFilter.Read(buffer, offset, count);
63        }
64
65        publicoverridelong Seek(long offset, SeekOrigin origin)
66ExpandedSubBlockStart.gif        {
67            return _StreamFilter.Seek(offset, origin);
68        }
69
70        publicoverridevoid SetLength(long value)
71ExpandedSubBlockStart.gif        {
72            _StreamFilter.SetLength(value);
73        }
74
75        publicoverridevoid Write(byte[] buffer, int offset, int count)
76ExpandedSubBlockStart.gif        {
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的資料也不多,有些也說得不是那麼清楚,所以,做個筆記.

posted on 2008-07-22 14:07 狼Robot 閱讀(1986) 評論(28)  編輯 收藏 所屬分類: C#