好久沒有寫技術文章,如果大家看不明白,就多看幾篇,汗,或者,在文章的後面回复(這是最有效的辦法),我會盡力幫助大家解答疑惑.
來找這篇文章的,應該都知道什麼叫二級域名吧,廢話就不說了.但是討論前,先要明白一個思想問題.
很多朋友一直考慮不清(我前幾天也一直搞不明白)的問題是,我鍵入一個地址後,怎麼這個url就被重寫了?
第一步:在瀏覽器鍵入了一個地址,例如http://blog.downcodes.com ,點回車後,都發生了什麼事?
為了把問題簡單化,我來這樣解釋:
第二步:首先,鍵入的位址被解析,最終來到了一台web伺服器.交給IIS處理.在.net的世界中,IIS會把這樣的請求再交給一個web處理器處理,最後,該web處理器把處理的結果回傳給瀏覽器,顯示給用戶看.
請不用忽略這樣一個問題,第二步的所有事情都是在伺服器端做的.在這些事情進行的時候,用戶端的瀏覽器上面的地址不會改變.即使最後web處理器把處理結果返回來的時候,上面的地址也不會改變.
一開始鍵入的url,只是起一個敲門的作用,門敲完了,作用就算結束了,只有你的眼睛可以看到那個地址,瀏覽器,伺服器等都不知道這個地址.
然後要明白的問題是,所謂url重寫,也只是web開發人員知道的內幕情況,用戶根本不知道發生了什麼,他認為自己鍵入的地址就是應該出來屏幕上顯示的結果.也就是說,我們在幕後控制要顯示的內容.
接下來要考慮的是,怎麼樣控制顯示的內容?
從上面說的過程,很明顯要在web處理器的工作這一步動手腳.
一個最簡單的考慮是,用戶敲入了一個簡單的不帶任何參數地址, http://blog.downcodes.com然後我們把這個位址改成一個符合程式需要的帶參數的位址, http://kerry.com?lover=notus ,最後處理之.
所謂的url重寫,就是在這一步.
用.net的術語來說,我們需要給應用程式註冊一個httpmodule,用來處理特定的url
註冊httpmodule,在web.config,
處理url,在我們提供的httpmodule程式中
大體相當於這樣的一段程式
//用我們的httpmodule程式截獲原始url
String OriginalUrl=” http://blog.downcodes.com ”;
//處理原始url,得到最後需要的url,值為http://kerry.com?lover=notus
String FinalUrl=Rewrite(OriginalUrl);
// context重新將url在內部傳送給IIS處理
context.RewritePath(FinalUrl);
接下來,我們來實作url重寫.
第一步:確定要對哪些url執行重寫,即制定重寫規則第二步:編寫httpmodule處理程序第三步:將編寫的httpmodule整合入web程序,開始工作.
上面就是url重寫的基本知識,而用url重寫實現二級域名,過程一樣.因為無論是二級域名還是三級域名,都是一個url地址.只要我們截獲這個url地址,就可以在處理的時候動手腳.
這些工作挺麻煩,但是網路上已經有高人給我們寫了這樣的程式,參考下面的文章:
http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx
http:/ /www.cnblogs.com/jzywh/archive/2005/09/29/246650.html
http://www.cnblogs.com/jzywh/archive/2006/02/20/334004.html
文章結束了.
在實施過程中會碰到一些問題,大多是因為看上面的文章不仔細產生的,但是說實話,那麼長的文章要看完也不容易.下面我來記錄一些重要的問題.其中最後的兩個問題,用具體的程式碼展示如何處理重寫的目標url以達到我們的要求
微軟的URLRewriter是什麼?這個專案在哪裡下載的?
這是在msdn上一篇介紹URLRewriter的文章中提供的範例程式,可以在這裡下載到
http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx
怎麼使用這些代碼?麻煩嗎?
肯定的說,不麻煩,要做的事情有:
下載代碼到你的機器上.
安裝後,把URLRewriter這個專案加入到你自己的工程中按照上面給的地址裡的方法,修改代碼配置web.config,開始使用.
什麼是httpmodule?
簡單理解,就是一塊處理http請求的程序更詳細的理解,請查閱sdk文檔.
怎麼樣實現泛解析?
首先,在網域服務商那裡新增一個*.kerry.com的二級網域,指向你的伺服器ip
然後,在IIS裡建立一個站點,這個站點的主機頭留空,一般端口是80. 這個站點就是整個伺服器端口80的預設網站.
給這個站點添加一個通配符應用程式映射(IIS站點屬性->主目錄-> 配置),這個映射的目的是要asp.net ISAPI接管任何沒有在IIS裡明確的二級域名站點.
隨便輸入二級域名的時候,發生了什麼事?
當IIS檢測到傳入的url是一個二級域名的時候,它會先檢查IIS上有沒有註冊了這個二級域名的站點,如果有,就轉入到這個站點,否則,就會轉到默認站點,這個預設站點就是之前配置的主機頭為空的那個站點.所以,一個連接埠只能有一個主機頭為空的站點.
我們已經設定由asp.net ISAPI接管這些沒有家的孩子.寫程式,分析傳入的url,執行重寫.
為什麼我的httpmodule好像沒有起作用?
在httpmodule程式裡設定斷點後,無論怎麼樣,流程都沒有從這裡走.原因在於,你沒有向web程式註冊你的httpmodule程式.這個工作需要在web.config中完成.
<system.web>
<httpModules>
<add type="URLRewriter.ModuleRewriter, URLRewriter" name="ModuleRewriter" />
</httpModules>
</system.web>
為什麼總是提示我」未知的設定節RewriterConfig錯誤」
這是因為你沒有向web程式註冊你的RewriterConfig設定節. 這個工作需要在web.config中完成.
<configSections>
<section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
</configSections>
然後,你可以在<configuration>裡使用RewriterConfig節設定規則了.
url是在httpmodule的哪個部分處理的?
大多的工作是在URLRewriter. ModuleRewriter. Rewrite()方法裡.關鍵階段是這裡:
if (re.IsMatch(requestedPath))
很明顯,這個判斷傳入的url是否是我們要重寫的url,大家接著看,
String sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
這裡接受到web.config中配置的要轉到的目標url
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
在內部把url重寫.
我不想把二級網域寫死在web.config中,而且我要重寫的目標url也不能寫死.例如我們有這樣的需要
blog.downcodes.com實際的處理頁面是kerry.com/action.aspx?id=1
call.kerryl.com實際的處理頁面是kerry.com/action.aspx?id=2
walkwith.kerry.com實際的處理頁面是kerry.com/walk.aspx
要怎麼處理?
這時候,就需要在上面說的那幾個程式碼裡做手腳.
if (re.IsMatch(requestedPath))
{
//找到url裡的二級域名
string [] UserHost = app.Request.Url.Host.Split ( new Char [] { '.' } );
string domain2=UserHost [0];
//依需求設定要重寫的目標url
string sendToUrl ;
if(domain2==” Love”)
sendToUrl =” /action.aspx?id=1”;
else if(domain2==” call”)
sendToUrl =” /action.aspx?id=2”;
else if(domain2==” walkwith”)
sendToUrl =” /walk.aspx”;
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
}
在web.config裡配置規則的時候,需要這樣
<RewriterRule>
<LookFor>http://(w+).kerry.com</LookFor>
<SendTo>/test.aspx</SendTo>
</RewriterRule>
(w+)用來匹配任意字串這裡的test.aspx隨便寫別的也可以,因為我們根本沒有用它.
我有很多不確定二級域名的站點,但是每個站點的頁面確定,每個二級域名站點的內容實際上根劇不同的id從數據庫調,
情況如這樣
http://localhost/kerry/action.aspx?id=1 blog.downcodes.com/walk.aspx
http://localhost/kerry/action.aspx?id=14 like.kerry.com/walk.aspx
現在傳上去,不能顯示id參數,都改成二級域名的方式. 這時候該怎麼辦?
先配置規則
<RewriterRule>
<LookFor>http://(w+).kerry .com walk.aspx</LookFor>
<SendTo>/action.aspx</SendTo>
</RewriterRule>
然後在程式裡這樣處理
//取得二級域名
string [] UserHost = app.Request.Url.Host.Split ( new Char [] { '.' } );
string domain2=UserHost [0];
根據域名取得不同的編號
int id=getIDfromDomain(domain2);
//獲得要轉向的基本url
string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
//加上id參數
if(id>0)
sendToUrl=string.Format ( "{0}?id={1}" , sendToUrl , id );
else
sendToUrl=”error.aspx”;
//重寫
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
我搜尋網路上還有另一個解決方法…
或許你是指這篇文章
http://blog.csdn.net/mengyao/archive/2007/01/25/ 1493537.aspx
大家可以看到,其基本的方法都是一樣的.之所以沒有把這個列在最前面,是因為這個做法有些取巧,可能一開始不是那麼好理解.但是我相信看到最後的朋友再看這篇文章,應該都會心的一笑
Happy programming
最後ps:本來準備過幾天發這個文章,就在剛才,不小心從VSS把這幾天寫的程式都刪除了,還是徹底型的,再次強烈的鄙視微軟做的這個垃圾源碼管理器-_ -