1. 程式人生 > >利用URL重寫實現引數目錄化

利用URL重寫實現引數目錄化

               

引數目錄化,就是將 類似 http://www.abc.com/store/store.aspx?id=1024 這樣的網址,對外改為 http://www.abc.com/1024

要實現這種功能,可以用以下三種方式(應該不僅限這三種吧!)

1、用微軟的 Microsoft URL 重寫模組 2.0,但只能給IIS7使用,IIS6不行。

64位:

32位:

2、isapi_rewrite

但完全版有日期限制,如果不想掏錢,有大牛破解了,可以用下面這個:

3、urlrewriter.net

這個有原始碼,可以自己編譯。

機緣巧合之下,我用了方法一 和 二。因為開發機器是WIN7,裝了IIS7,所以用微軟的重寫模組;而伺服器是WIN2003,就用了isapi_rewrite。

下面就這兩種方法分別做一點心得介紹。

事實上,這兩種方法大同小異,IIS基本上不用怎麼配置,沒有網上說的那麼玄妙,又是勾選,又是對映,又是許可權之類,關鍵在於要寫對正則表示式。

1、微軟的 Microsoft URL 重寫模組 2.0

安裝好之後,就可以改寫網站下的web.config了。

<configuration>  <system.web>    <compilation debug="true" targetFramework="4.0"/>    <httpRuntime/>  </system.web>  <system.webServer
>
    <rewrite>      <rules> <!-- 實現http://localhost/1024 ==> http://localhost/store/store.aspx?id=1024 -->        <rule name="storecode">          <match url="^([1-9][0-9]*)/?$" ignoreCase="true"/>          <action type="Rewrite" url="/store/store.aspx?id={R:1}"/>        </rule
>
 <!-- 實現http://localhost/1024/p=1&c=1 ==> http://localhost/store/store.aspx?id=1024&p=1&c=1 -->        <rule name="storecode with param">          <match url="^([1-9][0-9]*)/([^/]+)/?$" ignoreCase="true"/>          <action type="Rewrite" url="/store/store.aspx?id={R:1}&{R:2}"/>        </rule> <!-- 下面這些據說是從Discuz論壇裡匯出來的,肯定是正確的,供學習借鑑 -->        <!--                <rule name="已匯入的規則 1">                    <match url="^userinfo-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="userinfo.aspx?userid={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 2">                    <match url="^showforum-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="showforum.aspx?forumid={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 3">                    <match url="^showtopic-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="showtopic.aspx?topicid={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 4">                    <match url="^showforum-([0-9]+)-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="showforum.aspx?forumid={R:1}&page={R:2}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 5">                    <match url="^showtopic-([0-9]+)-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="showtopic.aspx?topicid={R:1}&page={R:2}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 6">                    <match url="^archiver/showforum-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="archiver/showforum.aspx?forumid={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 7">                    <match url="^archiver/showtopic-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="archiver/showtopic.aspx?topicid={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 8">                    <match url="^archiver/showtopic-([0-9]+)-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="archiver/showtopic.aspx?topicid={R:1}&page={R:2}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 9">                    <match url="^archiver/showforum-([0-9]+)-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="archiver/showforum.aspx?forumid={R:1}&page={R:2}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 10">                    <match url="^tools/rss-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="tools/rss.aspx?forumid={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 11">                    <match url="^tools/spacerss-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="tools/rss.aspx?uid={R:1}&type=space" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 12">                    <match url="^tools/photorss-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="tools/rss.aspx?uid={R:1}&type=photo" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 13">                    <match url="^space\/((\w|\s)+)((\/?))?$" ignoreCase="false" />                    <action type="Rewrite" url="space/index.aspx?user={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 14">                    <match url="^space\/((\w|\s|-)+)((\/?))?\?((.*)+)$" ignoreCase="false" />                    <action type="Rewrite" url="space/index.aspx?user={R:1}&{R:5}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 15">                    <match url="^showdebate-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="showdebate.aspx?topicid={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 16">                    <match url="^showbonus-([0-9]+)\.html$" ignoreCase="false" />                    <action type="Rewrite" url="showbonus.aspx?topicid={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 17">                    <match url="^postgoods-(\d+)*.html$" ignoreCase="false" />                    <action type="Rewrite" url="postgoods.aspx?categoryid={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 18">                    <match url="^showgoodslist-(\d+)(-(\d+))?.html$" ignoreCase="false" />                    <action type="Rewrite" url="showgoodslist.aspx?categoryid={R:1}&page={R:3}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 19">                    <match url="^showgoods-(\d+)*.html$" ignoreCase="false" />                    <action type="Rewrite" url="showgoods.aspx?goodsid={R:1}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 20">                    <match url="^install((\/?))?$" ignoreCase="false" />                    <action type="Rewrite" url="/install{R:1}" />                </rule>                <rule name="已匯入的規則 21">                    <match url="^upgrade((\/?))?$" ignoreCase="false" />                    <action type="Rewrite" url="/upgrade{R:1}" />                </rule>                <rule name="已匯入的規則 22">                    <match url="^aspx/([0-9]+)((\/?))?$" ignoreCase="false" />                    <action type="Rewrite" url="/aspx/{R:1}{R:2}" />                </rule>                <rule name="已匯入的規則 23">                    <match url="^archiver((\/?))?$" ignoreCase="false" />                    <action type="Rewrite" url="/archiver{R:1}" />                </rule>                <rule name="已匯入的規則 24">                    <match url="^space((\/?))?$" ignoreCase="false" />                    <action type="Rewrite" url="/space{R:1}" />                </rule>                <rule name="已匯入的規則 25">                    <match url="^doc((\/?))?$" ignoreCase="false" />                    <action type="Rewrite" url="/doc{R:1}" />                </rule>                <rule name="已匯入的規則 26">                    <match url="^(([\w|\-|_])+)((\/?))?$" ignoreCase="false" />                    <action type="Rewrite" url="/{R:1}/list.aspx" />                </rule>                <rule name="已匯入的規則 27">                    <match url="^(([\w|\-|_])+)((\/?))?\?(.)*$" ignoreCase="false" />                    <action type="Rewrite" url="/{R:1}/list.aspx?{R:2}" appendQueryString="false" />                </rule>                <rule name="已匯入的規則 28">                    <match url="^(([\w|\-|_])+)/([0-9]+)((\/?))?$" ignoreCase="false" />                    <action type="Rewrite" url="/{R:1}/{R:3}/list.aspx" />                </rule>                <rule name="已匯入的規則 29">                    <match url="^(([\w|\-|_])+)/([0-9]+)((\/?))?\?(.)*$" ignoreCase="false" />                    <action type="Rewrite" url="/{R:1}/{R:3}/list.aspx?{R:4}" appendQueryString="false" />                </rule>-->      </rules>    </rewrite>  </system.webServer></configuration>
關鍵是要寫對正則表示式,否則系統會報無法找到資源的404錯誤。真他媽的。就不能報點別的錯誤?害得我在網上瘋狂搜索,以為差了哪裡沒配置,還差點將IIS重灌了。網上也不會告訴你這個答案,他們只是建議將檔案是否存在的選項去掉,諸如此類。

HTTP 錯誤 404.0 - Not Found

您要找的資源已被刪除、已更名或暫時不可用。

同一站內的,就用Rewrite,目標頁面在另一站點的,則用 Redirect。如

          <rule name="img show">              <match url="^showimg/([a-zA-Z_0-9]+)/([1-9][0-9]*)/?$" ignoreCase="true"/>              <action type="Redirect" url="http://localhost:8006/handler.ashx?{R:1}={R:2}"/>          </rule>

2、isapi_rewrite

安裝之後,就可以直接使用了。開啟IIS6,點選網站-屬性,會看到:

點 EDIT,會在網站根目錄下生成一個.htaccess檔案。在裡面編寫我們的正則表示式:

# Helicon ISAPI_Rewrite configuration file# Version 3.1.0.87RewriteRule ^([1-9][0-9]*)/eurl\.axd/  /store/store.aspx\?id=$1 [NC]RewriteRule ^([1-9][0-9]*)/([^/]*)?/? /store/store.aspx\?id=$1&$2 [NC]
其正則表示式的語法,似乎跟微軟的URL重寫模組沒有多大區別,並且它還自帶了一個正則表示式測試器,開啟.htaccess檔案的時候,在編輯器選單裡可以看到,RegExp test

然後IIS6還要將Isapi_rewrite.dll作為篩選器器

但我發現有以下幾點需要注意:

1、正則表示式裡,不能出現問號(“\?”),否則一定匹配失敗,但正則表示式絕對正確,放在其他正則表示式測試器裡測試,也OK,但在這裡就不行。不知道什麼原因。翻遍網際網路,有個兄弟說:

這是因為 url 裡面 ? 後面的不被 apache 認為是 requested uri 的內容,所以你怎麼寫都無法取得。建議你修改 url 格式:比如把 ? 去掉;或者改變獲取方式:比如改成 RewriteRule /?(.*)$ /reg.php?id=$1&%

但我這個是IIS耶!真搞不懂,不管了。所以我原本想將優化後的地址設為:http://www.abc.com/1024?p=1&c=1的,結果怎麼試都不成功,最後只能放棄問號,改成:http://www.abc.com/1024/p=1&c=1

2、IIS6 + .net 4的情況下,IIS會自動在無後綴(什麼叫無後綴?不懂)地址後加上 "/eurl.axd/guid號",剛好跟我機器一樣。本來這個在ASP.NET處理過程中,會被自動去掉,但在這裡,經過轉向後,居然還保留了下來,我在測試過程中,在目標頁面顯示 Request.QueryString,居然可恥地顯示出這種不速之客:

網上有文章介紹用修改登錄檔的方式來遮蔽

但我想著以後可能會採用MVC模式,所以只在寫正則表示式時將這個因素考慮進去了:

RewriteRule ^([1-9][0-9]*)/eurl\.axd/  /store/store.aspx\?id=$1 [NC]

3、每條規則後面必要時要帶上適當的flag。

isapi_rewrite的RewriteRule就是後面常常帶上一些古怪的標識,比如[NC]、[L]之類,它們是幹什麼的?

其實它們很有用,比如:

[NC],忽略大小寫

[L],在一連串的匹配規則中,當系統找到第一個匹配的規則後,就不再往下匹配其他規則了。這個特別有用,比如:

我有1、2、3三條規則,有個輸入情況按照我的設想,是應該規則2起作用,最為匹配,但規則3是規則2的超集,同樣也可以匹配。如果規則2後面沒有這個[L]標識,那麼起作用的,會是規則3!

[R],立即轉向,比如將某個輸入,Redirect到別的網站或網址啦,使用這個標識,我感覺速度會快一點。

還有許多標識(flag),可以查閱這裡:

是英文的,但作為一個計算機程式設計師,我們還是要習慣閱讀英文文件,這有時比直接閱讀那些翻譯得奇形怪狀的中文文件還好理解。有時候我覺得老外程式設計那麼厲害,常常提出這思想那思想,這模式那模式,是因為他們閱讀、交流沒有什麼障礙,接受東西就比我們快。我們吃了這個虧。

我自己的英文非常爛,很不習慣讀英文文件,但從今往後,要慢慢習慣了。與豬君共勉!