|
http://www.jb51.NET/article/20906.htm
好久沒有寫技術(shù)文章,如果大家看不明白,就多看幾篇,汗,或者,在文章的后面回復(fù)(這是最有效的辦法),我會(huì)盡力幫助大家解答疑惑.
來找這篇文章的,應(yīng)該都知道什么叫二級(jí)域名吧,廢話就不說了.但是討論前,先要明白一個(gè)思想問題.
很多朋友一直考慮不清(我前幾天也一直搞不明白)的問題是,我鍵入一個(gè)地址后,怎么這個(gè)url就被重寫了?
第一步:在瀏覽器鍵入了一個(gè)地址,比如http://love.kerry.com,點(diǎn)回車后,都發(fā)生了什么?
為了把問題簡(jiǎn)單化,我來這樣解釋:
第二步:首先,鍵入的地址被解析,最終來到了一臺(tái)web服務(wù)器.交給IIS處理.在.NET的世界中,IIS會(huì)把這樣的請(qǐng)求再交給一個(gè)web處理器 處理,最后,該 web處理器 把處理的結(jié)果返回給瀏覽器,顯示給用戶看.
請(qǐng)不用忽略這樣一個(gè)問題,第二步的所有事情都是在服務(wù)器端做的.在這些事情進(jìn)行的時(shí)候,用戶端的瀏覽器上面的地址不會(huì)改變.即使最后 web處理器 把處理結(jié)果返回來的時(shí)候,上面的地址也不會(huì)改變.
一開始鍵入的url,只是起一個(gè)敲門的作用,門敲完了,作用就算結(jié)束了,只有你的眼睛可以看到那個(gè)地址,瀏覽器,服務(wù)器等都不知道這個(gè)地址.
然后要明白的問題是,所謂url重寫,也只是web開發(fā)人員知道的內(nèi)幕情況,用戶根本不知道發(fā)生了什么,他認(rèn)為自己鍵入的地址就是應(yīng)該出來屏幕上顯示的結(jié)果.也就是說,我們?cè)谀缓罂刂埔@示的內(nèi)容.
接下來要考慮的是,怎么樣控制顯示的內(nèi)容?
從上面說的過程,很明顯要在 web處理器 的工作這一步動(dòng)手腳.
一個(gè)最簡(jiǎn)單的考慮是,用戶敲入了一個(gè)簡(jiǎn)單的不帶任何參數(shù)地址, http://love.kerry.com然后我們把這個(gè)地址改成一個(gè)符合程序需要的帶參數(shù)的地址, http://kerry.com?lover=notus,最后處理之.
所謂的url重寫,就是在這一步.
用.NET的術(shù)語(yǔ)來說,我們需要給應(yīng)用程序注冊(cè)一個(gè)httpmodule,用來處理特定的url
注冊(cè)httpmodule,在web.config,
處理url,在我們提供的httpmodule程序中
大體相當(dāng)于這樣的一段程序
//用我們的httpmodule程序截獲原始url
String OriginalUrl=” http://love.kerry.com”;
//處理原始url,得到最后需要的url,值為http://kerry.com?lover=notus
String FinalUrl=Rewrite(OriginalUrl);
// context重新將url在內(nèi)部發(fā)送給IIS處理
context.RewritePath(FinalUrl);
接下來,我們來實(shí)現(xiàn)url重寫.
第一步:確定要對(duì)哪些url執(zhí)行重寫,即制定重寫規(guī)則
第二步:編寫httpmodule處理程序
第三步:將編寫的httpmodule整合入web程序,開始工作.
上面就是url重寫的基本知識(shí),而用url重寫實(shí)現(xiàn)二級(jí)域名,過程一樣.因?yàn)闊o論是二級(jí)域名還是三級(jí)域名,都是一個(gè)url地址.只要我們截獲這個(gè)url地址,就可以在處理的時(shí)候動(dòng)手腳.
這些工作挺麻煩,但是網(wǎng)絡(luò)上已經(jīng)有高人給我們寫了這樣的程序,參看下面的文章:
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
文章結(jié)束了.
在實(shí)施過程中會(huì)碰到一些問題,大多是因?yàn)榭瓷厦娴奈恼虏蛔屑?xì)產(chǎn)生的,但是說實(shí)話,那么長(zhǎng)的文章要看完也不容易.下面我來記錄一些重要的問題.其中最后的兩個(gè)問題,用具體的代碼展示了如何處理重寫的目標(biāo)url以達(dá)到我們的要求
為什么非要用泛解析?
看了好多朋友的回復(fù),我想現(xiàn)在可能有這樣的誤解,即,這篇關(guān)于url重寫的文章只是給大家介紹一些處理方法.至于泛解析不泛解析,并不重要.
如果你不需要實(shí)現(xiàn)任意二級(jí)域名,那就用不著去實(shí)現(xiàn)泛解析,直接把你需要的二級(jí)域名定死,然后在url重寫里處理好了!
再退一步,如果連二級(jí)域名都不用實(shí)現(xiàn),僅僅是對(duì)一個(gè)固定域名下的url進(jìn)行重寫,那都不需要修改msdn的那個(gè)urlrewriter,直接拿來用就可以實(shí)現(xiàn)了簡(jiǎn)單的url重寫. zyw對(duì)這個(gè)項(xiàng)目進(jìn)行的修改,只是為了取到全部的url進(jìn)行更大限度的控制.而如我們所見,一開始msdn的那個(gè)urlrewriter并不關(guān)心域名的問題
我一開始給文章起這樣的題目,是因?yàn)樽罱翼?xiàng)目里用到了,寫文檔的時(shí)候順便就把這個(gè)文章寫了
微軟的URLRewriter是什么?這個(gè)項(xiàng)目在哪里下載的?
這個(gè)是在msdn上一篇介紹URLRewriter的文章中提供的示例程序,可以在這里下載到
http://www.microsoft.com/china/msdn/library/webservices/ASP.NET/URLRewriting.mspx
怎么使用這些代碼?麻煩嗎?
肯定的說,不麻煩,要做的事情有:
下載代碼到你的機(jī)器上.
安裝后,把URLRewriter這個(gè)項(xiàng)目添加到你自己的工程中
按照上面給的地址里的方法,修改代碼
配置web.config,開始使用.
什么是httpmodule?
簡(jiǎn)單理解,就是一塊處理http請(qǐng)求的程序
更詳細(xì)的理解,請(qǐng)查閱sdk文檔.
怎么樣實(shí)現(xiàn)泛解析?
首先,在域名服務(wù)商那里添加一個(gè)*.kerry.com的二級(jí)域名,指向你的服務(wù)器ip
然后,在IIS里建立一個(gè)站點(diǎn),這個(gè)站點(diǎn)的主機(jī)頭留空,一般端口是80. 這個(gè)站點(diǎn)就是整個(gè)服務(wù)器端口80的默認(rèn)網(wǎng)站.
給這個(gè)站點(diǎn)添加一個(gè)通配符應(yīng)用程序映射(IIS站點(diǎn)屬性 ->主目錄 -> 配置),這個(gè)映射的目的是要ASP.NET ISAPI接管任何沒有在IIS里明確的二級(jí)域名站點(diǎn).
隨便輸入二級(jí)域名的時(shí)候,發(fā)生了什么?
當(dāng)IIS檢測(cè)到傳入的url是一個(gè)二級(jí)域名的時(shí)候,它會(huì)先檢查IIS上有沒有注冊(cè)了這個(gè)二級(jí)域名的站點(diǎn),如果有,就轉(zhuǎn)入到這個(gè)站點(diǎn),否則,就會(huì)轉(zhuǎn)到默認(rèn)站點(diǎn),這個(gè)默認(rèn)站點(diǎn)就是之前配置的主機(jī)頭為空的那個(gè)站點(diǎn).所以,一個(gè)端口只能有一個(gè)主機(jī)頭為空的站點(diǎn).
我們已經(jīng)設(shè)定由ASP.NET ISAPI接管這些沒有家的孩子.寫程序,分析傳入的url,執(zhí)行重寫.
為什么我的httpmodule好像沒有起作用?
在httpmodule程序里設(shè)置斷點(diǎn)后,無論怎么樣,流程都沒有從這里走.原因在于,你沒有向web程序注冊(cè)你的httpmodule程序.這個(gè)工作需要在web.config中完成.
<system.web>
<httpModules>
<add type="URLRewriter.ModuleRewriter, URLRewriter" name="ModuleRewriter" />
</httpModules>
</system.web>
為什么總是提示我”未知的配置節(jié)RewriterConfig錯(cuò)誤”
這是因?yàn)槟銢]有向web程序注冊(cè)你的RewriterConfig配置節(jié). 這個(gè)工作需要在web.config中完成.
<configSections>
<section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
</configSections>
然后,你可以在<configuration>里使用RewriterConfig節(jié)配置規(guī)則了.
url是在httpmodule的哪個(gè)部分處理的?
大多的工作是在URLRewriter. ModuleRewriter. Rewrite()方法里.關(guān)鍵階段是這里:
if (re.IsMatch(requestedPath))
很明顯,這個(gè)判斷傳入的url是否是我們要重寫的url,大家接著看,
String sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
這里接受到web.config中配置的要轉(zhuǎn)到的目標(biāo)url
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
在內(nèi)部把url重寫.
我不想把二級(jí)域名寫死在web.config中,而且我要重寫的目標(biāo)url也不能寫死.比如我們有這樣的需要
Love.kerry.com實(shí)際的處理頁(yè)面是kerry.com/action.ASPx?id=1
call.kerryl.com實(shí)際的處理頁(yè)面是kerry.com/action.ASPx?id=2
walkwith.kerry.com實(shí)際的處理頁(yè)面是kerry.com/walk.ASPx
要怎么處理?
這個(gè)時(shí)候,就需要在上面說的那幾個(gè)代碼里做手腳.
if (re.IsMatch(requestedPath))
{
//找到url里的二級(jí)域名
string [] UserHost = app.Request.Url.Host.Split ( new Char [] { '.' } );
string domain2=UserHost [0];
//根據(jù)需要設(shè)定要重寫的目標(biāo)url
string sendToUrl ;
if(domain2==” Love”)
sendToUrl =” /action.ASPx?id=1”;
else if(domain2==” call”)
sendToUrl =” /action.ASPx?id=2”;
else i f(domain2==” walkwith”)
sendToUrl =” /walk.ASPx”;
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
}
在web.config里配置規(guī)則的時(shí)候,需要這樣
<RewriterRule>
<LookFor>http://(/w+)/.kerry/.com</LookFor>
<SendTo>/test.ASPx</SendTo>
</RewriterRule>
(/w+)用來匹配任意字符串
這里的test.ASPx隨便寫別的也可以,因?yàn)槲覀兏緵]有用它.
我有好多不確定二級(jí)域名的站點(diǎn),但是每個(gè)站點(diǎn)的頁(yè)面確定,每個(gè)二級(jí)域名站點(diǎn)的內(nèi)容實(shí)際上根劇不同的id從數(shù)據(jù)庫(kù)調(diào),
情況如這樣
http://localhost/kerry/action.ASPx?id=1 love.kerry.com/walk.ASPx
http://localhost/kerry/action.ASPx?id=14 like.kerry.com/walk.ASPx
現(xiàn)在傳上去,不能顯示id參數(shù),都改成二級(jí)域名的方式. 這個(gè)時(shí)候該怎么辦?
首先配置規(guī)則
<RewriterRule>
<LookFor>http://(/w+)/.kerry /.com/ walk.ASPx</LookFor>
<SendTo>/action.ASPx</SendTo>
</RewriterRule>
然后在程序里這樣處理
//獲取二級(jí)域名
string [] UserHost = app.Request.Url.Host.Split ( new Char [] { '.' } );
string domain2=UserHost [0];
根據(jù)域名獲得不同的編號(hào)
int id=getIDfromDomain(domain2);
//獲得要轉(zhuǎn)向的基本url
string sendToUrl = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, rules[i].SendTo));
//加上id參數(shù)
if(id>0)
sendToUrl=string.Format ( "{0}?id={1}" , sendToUrl , id );
else
sendToUrl=”error.ASPx”;
//重寫
RewriterUtils.RewriteUrl(app.Context, sendToUrl);
如何匹配目錄?寫了一個(gè)lookfor規(guī)則 http://love.kerry.com/,但是在瀏覽器輸入這個(gè)地址, 總是不能正確的重寫,經(jīng)過trace后發(fā)現(xiàn)根本不能匹配,為什么?
首先,我們應(yīng)該知道,瀏覽器實(shí)際上接受的不是http://love.kerry.com/,而是http://love.kerry.com/default.ASPx ,因此,你的</LookFor>規(guī)則應(yīng)該這樣寫
<LookFor>
http://love.kerry.com/default.ASPx
</LookFor>
這個(gè)default.ASPx應(yīng)該是你在iis里配置的默認(rèn)文檔,如果你的是index.ASPx或其他奇怪的名字,就寫成你自己的名字
同樣, http://love.kerry.com/fun 這個(gè)地址要匹配,需要這樣的規(guī)則http://love.kerry.com/fun/default.ASPx
但是,再羅嗦一句,你的文件根本不需要有fun這個(gè)目錄,因?yàn)?..重寫了嘛
我搜到網(wǎng)上還有另外一種解決辦法…
或許你是指這篇文章
http://blog.csdn.NET/mengyao/archive/2007/01/25/1493537.ASPx
大家可以看到,其基本的方法都是一樣的.之所以沒有把這個(gè)列在最前面,是因?yàn)檫@個(gè)做法有些取巧,可能一開始不是那么好理解.但是我相信看到最后的朋友再看這篇文章,應(yīng)該都會(huì)會(huì)心的一笑
Happy programming
最后ps:本來準(zhǔn)備過幾天發(fā)這個(gè)文章,就在剛才,不小心從VSS把這幾天寫的程序都刪除了,還是徹底型的,再次強(qiáng)烈的鄙視微軟做的這個(gè)垃圾源碼管理器 -_-
AspNet技術(shù):asp.net用url重寫URLReWriter實(shí)現(xiàn)任意二級(jí)域名 高級(jí)篇,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。