MVC在IIS6中重寫

每一次看scottgurBLOG總能收穫意外的驚喜^_^。在他的這篇BLOGTip/Trick: Url Rewriting with ASP.NET(感謝思歸)中,描述了有關在ASP.NET重寫URL的各種方法。而我這篇文章不會涉及如何在ASP.NET重寫URL,只是簡單介紹IIRF(爲了方便少寫幾字,以後的Ionic's Isapi Rewrite Filter將全部簡寫)如何在IIS下面實現URL的重寫。

介紹

 IIRF是一款開源的重寫URL過濾器,類似於ApacheURL重寫,基於VC8.0(可以用Visual Studio2005Visual C++ 2005 Express重新編譯)開發。它可以運行在IIS5.0+,支持ASP,ASP.NET,PHP等許多格式。相對比ASP.NET2.0自帶的URL重寫,具有更好的性能和許多我們所需要特性,重要的一點在於:它可以支持無擴展名的URL(例如:cnlbogs.com/****,你無需在創建一個默認的default.aspx文件,IIRF自動會幫你解析),讓URL更加的方便我們記憶,也能進一步提高搜索的排名?IIRF能夠在aspnet_isapi提前捕獲我們所請求的URL進行處理,如果我們訪問cnlbogs.com/a.aspx,需要獲取cnlbogs.com/a.htm,步驟需要(iis-aspnet_isapi),通過IIRF,我們可以直接跳aspnet_isapi.dll,直接訪問a.htm,要知道,這種方式在ASP.NET是無法實現的。

 IIRFASP.NET重寫URL一樣,它也是基於正則的方式來匹配,具有LOG記錄,請求的條件判斷。還是進入正題吧。 

安裝

 IIRF安裝需要我們手動操作來完成。不過。也是很方便了。

IsapiRewrite4.dll, IsapiRewrite4.ini複製到c:\windows\system32\inetsrv(你也可以複製到其它適當的文件夾下面)

IsapiRewrite4.iniIIRF配置文件,每次該文件更改之後,IIRF會自動重新加載該文件,無需重啓IIS來重新加載配置,如果您修改後INI文件後格式不正確,IIRF將會自動獲取最後正確加載的配置文件。

2 打開IIS管理器,選擇“默認網站”,右擊“屬性”,選擇“ISAPI篩選器”,點擊“添加”,輸入篩選器名稱:Ionic Rewriter,可執行文件選擇上面複製到c:\windows\system32\inetsrv下面的IsapiRewrite4.dll文件,點“確定”。

3重啓IISADMIN service服務。(在計算機管理----windows服務裏面)

4 完成。

日誌

IIRF
能夠將INI配置文件加載,用戶的URL請求記錄都會保存到指定的日誌文件裏。因爲它具有很大的性能開銷,因此建議將它日誌的記錄等級設爲0,只有
爲了方便調試的時候時候,可以設置爲5

RewriteLog <filename stub>  保存的日誌路徑,如 c:\temp\iirfLog.out
RewriteLogLevel {0,1,2,3,4,5} 日誌的等級,默認值爲0

0 –不會記錄日誌
1- 少許的日誌
2-  比較多的日誌
3- 比較詳細的日誌
4- 詳細的日誌(4),並會跟蹤server variable和替換的字符串。
5- 詳細的日誌(5),包括日誌文件更改的事件,建議方便調試的時候使用

正則

正則的語法跟.NET一樣,只不過是格式不一樣而已。所以我也不在詳細介紹。具體有關正則的說明大家可以用GOOGLE搜索。

格式:
RewriteRule <url-pattern> <replacement-string>   [<modifiers>]
url-pattern:匹配的正則表達式(必需)
replacement-string:要替換的字符串(必需)
modifiers:有關對RewriteRule的操作標記。可選選項。在下面我會說明

默認下IIRF的url-pattern,replacement-string正則的前面已經帶了主機頭的。

爲了方便描述,直接看幾個示例
(以下示例基本全部來源IIRF文檔)

RewriteRule  ^/original/(.*).php  /modified/$1.aspx

源:http://xxx/original/index.php

目標:http://xxx/modified/index.aspx

RewriteRule  ^/dinoch/album/([^/]+)/([^/]+).(jpg|JPG|PNG)   /chiesa/pics.aspx?d=$1&p=$2.$3

源:http://xxx/dinoch/album/30/1.jpg

目標:http://xxx/chiesa/pics.aspx?d=30&p=1.jpg

 比較簡單,主要還在於modifiers的功能。下面列舉了它的所有值,允許組合([R,L])

   R = Redirect(URL跳轉到<replacement-string>地址)
   NF = Not found(返回404錯誤給用戶,但該文件並未移除,還是保留在網站中)
   = Last test if match(如果已經匹配,將不在繼續匹配下去)
   = Forbidden(跟NF標誌相似,)
   I = Do case-insensitive matching
   U = Store original url in server Variable HTTP_X_REWRITE_URL(保存原始的url到HTTP_X_REWRITE_URL服務器變量中。)

[R]  or [R=code]
就像跟我們在ASP.NET使用的Redirect方法一樣,重新改變瀏覽器的方向,跳轉到新的指定的URL中。
[R=code]允許我們指定特定的HTTP狀態返回碼。只能介於301到399。如果超出這個範圍。默認會是使用302狀態。
RewriteRule ^/goto.aspx?r=(.*)$ $1 [R]
源:http://xxx/goto.aspx?r=http://www.google.com/
目標:http://www.google.com


[L]
上面已經簡單介紹過。不在說明

[NF] 
上面已經簡單介紹過。它還可以跟RewriteCond一起配合,來實現自定義的404錯誤請求。
特別要注意,你所要匹配的文件必須存在,替換的字符串不允許是存在文件名
RewriteRule ^/1008.aspx$ /1.aspx [NF]
1008.aspx文件需要存在,1.aspx不存在,否則無法正常達到我們的結果。
(很奇怪,我不知道是不是我搞錯了。但我最終測試的結果確實是這樣,文檔也沒詳細說明過,有知道的朋友可以告訴我一下原因)

[F]
不在說明。

[I]
模糊匹配

[U]
保存原始的url到HTTP_X_REWRITE_URL服務器變量中。
在ASP.NET你可以用Request.ServerVariables["HTTP_X_REWRITE_URL"]獲取原始值。

RewriteCond
RewriteCond <test-string> <pattern> [<modifier flag[,...]>]
類似於條件判斷,並且允許多個條件,OR,AND。只有當RewriteCond的Server Variable 匹配所指定的正則表達,RewriteRule纔會執行。比如:
RewriteCond %{REMOTE_ADDR} ^(127.0.0.1)$
RewriteRule ^/(.*).aspx$ /$1.aspx
如果我們訪問網站的地址的IP來源於127.0.0.1,那麼,允許 RewriteRule ^/(.*).aspx$ /$1.aspx

RewriteCond %{REMOTE_ADDR} ^(127.0.0.1)$ [OR]
RewriteCond %{REMOTE_ADDR} ^(192.168.0.10)$
RewriteRule ^/(.*).aspx$ /$1.aspx
添加了OR來多個條件判斷

RewriteCond %{REMOTE_ADDR}   ^(?!127.0.0.1)([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})(.*)$
RewriteRule  ^/(?!redirected.htm)(.*)$      /redirected.htm

Modifier flags有二個值
I=模糊匹配
OR=邏輯判斷

從IIRF的RewriteCond的功能上來說,確實很靈活,不知道跟IIS7的重寫怎麼樣,嘻嘻。還沒瞧見過呢*^_&。另外。RewriteCond的[Patterns]可以帶下面幾個參數
 -d
  Treats the TestString as a pathname and tests if it exists,
  and is a directory.
TestString是一個路徑名稱,並且存在這個路徑
 -f
  Treats the TestString as a pathname and tests if it exists and
  is a regular file.
TestString是一個路徑名稱,並且是一個存在的文件
  -s 
  Treats the TestString as a pathname and tests if it exists and
  is a regular file with size greater than zero.
TestString 是一個路徑名稱,並且存在文件超過0字節

如文檔所使用的例子
(1)RewriteCond %{HTTP_URL}             (/|\.htm|\.php|\.html|/[^.]*)$   [I] )
(2)RewriteCond %{REQUEST_FILENAME}     !-f
(3)RewriteCond %{REQUEST_FILENAME}     !-d                                  
(4)RewriteRule ^.*$                    /index.aspx                      [U,L]
(1)如果URL是以htm,php,html(模糊匹配),
(2)URL不是存在文件
(3)URL不是請求的路徑
(4)將所有請求跳轉到index.aspx,保存原始的URL,之後不在對此進行匹配

在如
RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
RewriteRule  ^/$                 /homepage.max.html  [L]

IIRF其它配置屬性
IterationLimit {integer}從指定的integer後開始匹配RewriteRule組。如果超出RewriteRule個數,默認將會從第8個開始。
MaxMatchCount {integer} RewriteRule組的總個數。
RewriteLog <filename stub> 日誌路徑
RewriteLogLevel {0,1,2,3,4,5} 日誌的等級

一個常見問題
在剛安裝IIRF之後就測試一下ASP.NET下面的URL,發現還是跟以前ASP.NET重寫URL有一樣的問題:無法改寫Form下面的action的路徑,而我們這時使用Request.RawUrl獲取原始的URL是爲空的。也許你開始注意到了我上面寫過的RewriteRule的modifiers選項[U]。我們可以通過將原始的URL保存到服務器變量中。然後通過Request.ServerVariables[name]來獲取。然後重寫action的值就可以了。

 


 1 Public Class FormFixerHtmlTextWriter
 2
        
Inherits
 System.Web.UI.HtmlTextWriter
 3
        
Private _url As
 
String

 4        Public Sub New(ByVal writer As TextWriter)
 5
            
MyBase
.New(writer)
 6
            _url 
= ForumContext.Current.Context.Request.ServerVariables("
HTTP_X_REWRITE_URL
"
)
 7
        
End Sub

 8        Public Overloads Overrides Sub WriteAttribute(ByVal name As StringByVal value As StringByVal encode As Boolean)
 9
            
If (Not
 _url 
Is
 
Nothing
 
And
 
String
.Compare(name, 
"
action
"
True
=
 
0
Then

10                value = _url
11
            
End If

12            MyBase.WriteAttribute(name, value, encode)
13
        
End Sub

14    End Class

 

後記:
IIRF已經分析的差不多了。從上面可以看出,功能確實很強大,而且配置也很靈活。發現自己也慢慢喜歡上它了。嘿嘿。重要的是。它是免費,開源的。

爲自己小小的鼓掌一下。嘻嘻。寫這篇隨筆真不容易。希望能給大家一個幫助。另外,由於自己水平有限,上面也許有描述錯誤的地方或不清楚的地方還請指出,有則改之,無則加勉:)

最後,祝大家2007年的第一個周未愉快*^_^*

[2007-09-01]
http://zhangsichu.com/blogview.asp?Content_Id=82
這裏已經有人實現了二級域名的重寫,大家可以去看看.感謝 tombom 提供的信息.

IIRF網站:http://cheeso.members.winisp.net/IIRF.aspx

轉載自:http://www.cnblogs.com/cnzc/archive/2007/03/02/662217.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章