我們有時候會見到這樣的地址:“http://www.huoho.com/show-12-34.html”,你或許認爲在站點服務器根目錄“/”下存在名爲“show-12-34.html”的文件,其實實際它可能是不存在的,而可能你看到的內容是“/aspx/show.aspx?type= 12&id=34”的內容,爲什麼要這樣做呢?原因有多個方面:首先是增強URL的友好性,記“show-12-34.html”總比 “/aspx/show.aspx?type=12&id=34”好記吧?其次就是方便搜索引擎收錄,很多搜索引擎更看好靜態HTML頁,比如:百度;其次就是出於安全性的考慮,因爲這樣隱藏了參數“type”、“id”。是不是很有意思呢?
其實這是利用URL重寫實現的,下面我就說一下在ASP.NET2.0下我所知道的最簡單的實現方法:通過實現接口“IHttpHandler”來接管HTTP請求,Follow me!
1.在資源管理方案中添加一個類,類的代碼如下:
- //類URLRewriter程序清單:
- using System;
- using System.Data;
- using System.Configuration;
- using System.Web;
- using System.Web.Security;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- using System.Web.UI.WebControls.WebParts;
- using System.Web.UI.HtmlControls;
- /// <summary>
- /// UrlRewriter URL重寫類
- /// Author:yoyo
- /// blog:http://yangmingsheng.cn
- /// </summary>
- public class UrlRewriter : IHttpHandler //實現“IHttpHandler”接口
- {
- public UrlRewriter()
- {
- //
- // TODO: 在此處添加構造函數邏輯
- //
- }
- public void ProcessRequest(HttpContext Context)
- {
- try
- {
- //取得原始URL屏蔽掉參數
- string Url = Context.Request.RawUrl;
- //建立正則表達式
- System.Text.RegularExpressions.Regex Reg = new System.Text.RegularExpressions.Regex
- (@"/show-(\d+)-(\d+)\..+",System.Text.RegularExpressions.RegexOptions.IgnoreCase);
- //用正則表達式進行匹配
- System.Text.RegularExpressions.Match m =
- Reg.Match(Url,Url.LastIndexOf("/"));//從最後一個“/”開始匹配
- if (m.Success)//匹配成功
- {
- String RealPath =
- @"~/aspx/show.aspx?type=" + m.Groups[1] + "&id=" + m.Groups[2];
- //Context.Response.Write(RealPath);
- //Context.RewritePath(RealPath);//(RewritePath 用在無 Cookie 會話狀態中。)
- Context.Server.Execute(RealPath);
- }
- else
- {
- Context.Response.Redirect(Context.Request.Url.ToString());
- }
- }
- catch
- {
- Context.Response.Redirect(Context.Request.Url.ToString());
- }
- }
- /// <summary>
- /// 實現“IHttpHandler”接口所必須的成員
- /// </summary>
- /// <value></value>
- /// Author:yoyo
- /// blog:http://yangmingsheng.cn
- public bool IsReusable
- {
- get { return false; }
- }
- }
//類URLRewriter程序清單:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
/// <summary>
/// UrlRewriter URL重寫類
/// Author:yoyo
/// blog:http://yangmingsheng.cn
/// </summary>
public class UrlRewriter : IHttpHandler //實現“IHttpHandler”接口
{
public UrlRewriter()
{
//
// TODO: 在此處添加構造函數邏輯
//
}
public void ProcessRequest(HttpContext Context)
{
try
{
//取得原始URL屏蔽掉參數
string Url = Context.Request.RawUrl;
//建立正則表達式
System.Text.RegularExpressions.Regex Reg = new System.Text.RegularExpressions.Regex
(@"/show-(\d+)-(\d+)\..+",System.Text.RegularExpressions.RegexOptions.IgnoreCase);
//用正則表達式進行匹配
System.Text.RegularExpressions.Match m =
Reg.Match(Url,Url.LastIndexOf("/"));//從最後一個“/”開始匹配
if (m.Success)//匹配成功
{
String RealPath =
@"~/aspx/show.aspx?type=" + m.Groups[1] + "&id=" + m.Groups[2];
//Context.Response.Write(RealPath);
//Context.RewritePath(RealPath);//(RewritePath 用在無 Cookie 會話狀態中。)
Context.Server.Execute(RealPath);
}
else
{
Context.Response.Redirect(Context.Request.Url.ToString());
}
}
catch
{
Context.Response.Redirect(Context.Request.Url.ToString());
}
}
/// <summary>
/// 實現“IHttpHandler”接口所必須的成員
/// </summary>
/// <value></value>
/// Author:yoyo
/// blog:http://yangmingsheng.cn
public bool IsReusable
{
get { return false; }
}
}
2.在web.config文件還要添加一下設置項
在<system.web>節點下添加如下代碼:
- <httpHandlers>
- <add verb="*" path="*/show-?*-?*.aspx" type="UrlRewriter" />
- </httpHandlers>
<httpHandlers>
<add verb="*" path="*/show-?*-?*.aspx" type="UrlRewriter" />
</httpHandlers>
解釋一下:
verb是指允許的動作“GET”、“POST”、“PUT”中的一種或幾種,星號“*”表示全部允許;
path是指匹配路徑,支持簡單的通配符;
type是指綁定的類名以及包括命名空間(如果有的話);
對了,首先你要建立一個WEB窗體“show.aspx”在目錄“aspx”下,因爲這個文件就是實際接受請求並顯示相關內容的頁面。
OK!,編譯,打開網站輸入地址http://localhost:80/show-12-34.aspx 訪問一下,檢查看是不是顯示的“/aspx/show.aspx?type=12&id=34”的內容呢?!
上面我是設置了匹配ASPX文件,因爲IIS裏.HTML擴展名默認是不歸ASP.NET接管的,如果要接管HTML請求,
請將IIS的擴展名.HTML映射到“C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll”,
然後將上面的aspx改成html:
- <httpHandlers>
- <add verb="*" path="*/show-?*-?*.html" type="UrlRewriter" />
- </httpHandlers>
<httpHandlers>
<add verb="*" path="*/show-?*-?*.html" type="UrlRewriter" />
</httpHandlers>
現在打開網站輸入地址http://localhost:80/show-12-34.html 訪問一下~!
方法二:地址重寫、使用僞靜態、頁面回發處理
製作網站頁面的時候,有時候爲了用戶的體驗和搜索引擎的收錄,很多網站經常使用僞靜態地址重寫,或者稱爲 URL地址重寫的辦法,來將諸如:MyEbook.aspx?ID=1,MyEbook.aspx?ID=2MyEbook.aspx?ID=3等帶有參 數的動態頁面僞裝成爲一個靜態頁面,比如,將以上的僞裝成爲My1.html,My2.html,My3.html等等諸如此類!
出發點是很好的,不僅有利於用戶體驗,也有利於收錄,實在是一舉兩得!
好處已講,現在來談談使用這種辦法所存在的毛病,問題就在於,當你使用僞靜態技術的頁面有按鈕,需要提交內容時,這個時候,一旦與服務器之間有回發動作, 那麼,地址欄裏面顯示的網頁地址就不再是僞裝出來的My1.html,My2.html,My3.html等等拉,而是變爲MyEbook.aspx? ID=1,MyEbook.aspx?ID=2MyEbook.aspx?ID=3等等洛,如此一來,會讓不太懂網頁製作的網友感到不安,他們會認爲自己 在上一個騙子網站,認爲自己提交的數據都被另外一個網站給偷走了,總之,給他們的感覺就是,這樣的網站具有欺騙性質;很可能,以後他們再也不敢上你的網站 了!!!………
下面本人就個人解決如上問題的心得體會做如下說明,希望能夠幫助廣大網友解決問題!
解決如上問題,有很多種辦法,有使用Javascript禁止回發,有將頁面的
改爲等等多種方法,反正能改的地方,都有人使用過了,並且,這樣的文章比較多,但是難以實現,就本人脾氣而已,更喜歡直接了當的辦法,儘量少改地方,免得日後出錯麻煩;
第一步:打開你的網站下面,新建一個類,文件名稱大體如此:MyActionlessform.cs
第二步:該類的代碼如下:
- using System;
- using System.IO;
- using System.Web;
- using System.Web.UI;
- namespace MyURL
- {
- public class MyOLPage : Page
- {
- public MyOLPage()
- { }
- protected override void Render(HtmlTextWriter writer)
- {
- if (writer is System.Web.UI.Html32TextWriter)
- {
- writer = new FormFixerHtml32TextWriter(writer.InnerWriter);
- }
- else
- {
- writer = new FormFixerHtmlTextWriter(writer.InnerWriter);
- }
- base.Render(writer);
- }
- }
- internal class FormFixerHtml32TextWriter : System.Web.UI.Html32TextWriter
- {
- private string _url; // 僞裝的URL
- internal FormFixerHtml32TextWriter(TextWriter writer)
- : base(writer)
- {
- _url = HttpContext.Current.Request.RawUrl;
- }
- public override void WriteAttribute(string name, string value, bool encode)
- {
- if (_url != null && string.Compare(name, "action", true) == 0)
- {
- value = _url;
- }
- base.WriteAttribute(name, value, encode);
- }
- }
- internal class FormFixerHtmlTextWriter : System.Web.UI.HtmlTextWriter
- {
- private string _url;
- internal FormFixerHtmlTextWriter(TextWriter writer)
- : base(writer)
- {
- _url = HttpContext.Current.Request.RawUrl;
- }
- public override void WriteAttribute(string name, string value, bool encode)
- {
- if (_url != null && string.Compare(name, "action", true) == 0)
- {
- value = _url;
- }
- base.WriteAttribute(name, value, encode);
- }
- }
- }
using System;
using System.IO;
using System.Web;
using System.Web.UI;
namespace MyURL
{
public class MyOLPage : Page
{
public MyOLPage()
{ }
protected override void Render(HtmlTextWriter writer)
{
if (writer is System.Web.UI.Html32TextWriter)
{
writer = new FormFixerHtml32TextWriter(writer.InnerWriter);
}
else
{
writer = new FormFixerHtmlTextWriter(writer.InnerWriter);
}
base.Render(writer);
}
}
internal class FormFixerHtml32TextWriter : System.Web.UI.Html32TextWriter
{
private string _url; // 僞裝的URL
internal FormFixerHtml32TextWriter(TextWriter writer)
: base(writer)
{
_url = HttpContext.Current.Request.RawUrl;
}
public override void WriteAttribute(string name, string value, bool encode)
{
if (_url != null && string.Compare(name, "action", true) == 0)
{
value = _url;
}
base.WriteAttribute(name, value, encode);
}
}
internal class FormFixerHtmlTextWriter : System.Web.UI.HtmlTextWriter
{
private string _url;
internal FormFixerHtmlTextWriter(TextWriter writer)
: base(writer)
{
_url = HttpContext.Current.Request.RawUrl;
}
public override void WriteAttribute(string name, string value, bool encode)
{
if (_url != null && string.Compare(name, "action", true) == 0)
{
value = _url;
}
base.WriteAttribute(name, value, encode);
}
}
}
之後,將這個類文件編譯成爲MyActionlessform.dll文件,並在網站的項目中引用他,
第三步:打開具有回發操作的頁面,將其中的:System.Web.UI.Page更改爲: MyURL.MyOLPage,如此而已,一勞永逸了,以後不再擔心回發暴露真實地址嚇走網友拉!
至此,大功可成一半多一點,接下來問題又來了,什麼問題呢,你運行一下你的網站,是不是出現如下錯誤呀!
CS0433: 類型“MyURL.MyOLPage”同時存在於“c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ Temporary ASP.NET Files\schoolit\3266aab1\aca2fc74\App_Code.2-69spm5.dll”和“c:\WINDOWS\ Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\schoolit\3266aab1\aca2fc74\assembly\dl3\4d107fc6\00b753fe_ea19c801\ MyActionlessform.DLL”中
大體就是這樣的錯誤了,針對這樣的錯誤,有很多解決辦法,有的地方說,刪除臨時使用的文件夾,刪除某個命名 空間等等操作,俺都試過了,但是百試不得其果,後來俺就自己想想,出現這樣的錯誤無非就是兩個文件同時存在,但是又不能重複使用,解決辦法那還不簡單,停 用一個,只使用一個就行了嘛
上面的,我們不是建立了一個MyActionlessform.cs了嗎,它存在App_Code這個文件夾裏面,另外一個是 MyActionlessform.dll,兩個文件內容完全一樣,做好了,我們就不需要MyActionlessform.cs了,我們只需要 MyActionlessform.dll,那麼,想方設法將前者弄走不就得了(本人建議將此文件排除項目,不提倡直接刪除該文件,因爲以後可能使用 到),本人做法是,在項目中直接排出MyActionlessform.cs文件,經過測試,大功至此已結束!!!!
方法三:利用Mircosoft URLRewriter.dll實現頁面僞靜態
昨天,轉貼了一篇利用ISAPI篩選器來實現URL僞靜態的文章,我按照文章上的內容做,可是沒有做出來,目前看來,該方法沒有使用Microsoft URLRewriter.dll這個方法好,至少我個人覺得,花了一個晚上的時間,終於研究出來了怎麼利用這個dll文件來對asp.net頁面實現靜態 化了,其實很簡單。
一,獲得Mircosoft URLRewriter.dll:
獲得Mircosoft URLRewriter.dll可以到http://www.microsoft.com/china/msdn/library/webservices/asp.net/URLRewriting.mspx?mfr=true
這裏,選擇[下載本文的源代碼],下載完畢後,導入工程,我這裏沒有對該工程做任何修改,保留了原來的重寫方式,然後直接在VS2005裏面生成.dll文件就可以了。
二,使用該dll文件:
添加引用,搞定。
三,頁面方面的設計,這裏不在贅述了,我會放一個下載包,有興趣的朋友下載來看看吧,代碼寫的比較亂。
四,web.config的配置
這部是非常關鍵的,也是靜態化能否成功的關鍵。
- <?xml version="1.0"?>
- <configuration>
- <configSections>
- <section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
- </configSections>
- <RewriterConfig>
- <Rules>
- <RewriterRule>
- <LookFor>~/web/new/type/(.[0-9]*)\.html</LookFor>
- <SendTo>~/web/new.aspx?id=$1</SendTo>
- </RewriterRule>
- <RewriterRule>
- <LookFor>~/web/index.html</LookFor>
- <SendTo>~/web/index.aspx</SendTo>
- </RewriterRule>
- </Rules>
- </RewriterConfig>
- <system.web>
- <httpHandlers>
- <add verb="*" path="*.aspx" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
- <add verb="*" path="*.html" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
- </httpHandlers>
- <compilation debug="true"/></system.web>
- </configuration>
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
</configSections>
<RewriterConfig>
<Rules>
<RewriterRule>
<LookFor>~/web/new/type/(.[0-9]*)\.html</LookFor>
<SendTo>~/web/new.aspx?id=$1</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>~/web/index.html</LookFor>
<SendTo>~/web/index.aspx</SendTo>
</RewriterRule>
</Rules>
</RewriterConfig>
<system.web>
<httpHandlers>
<add verb="*" path="*.aspx" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
<add verb="*" path="*.html" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
</httpHandlers>
<compilation debug="true"/></system.web>
</configuration>
這裏簡單介紹一下:
- <RewriterConfig>
- <Rules>
- <RewriterRule>
- <LookFor>要查找的模式</LookFor>
- <SendTo>要用來替換模式的字符串</SendTo>
- </RewriterRule>
- <RewriterRule>
- <LookFor>要查找的模式</LookFor>
- <SendTo>要用來替換模式的字符串</SendTo>
- </RewriterRule>
- </Rules>
- </RewriterConfig>
<RewriterConfig>
<Rules>
<RewriterRule>
<LookFor>要查找的模式</LookFor>
<SendTo>要用來替換模式的字符串</SendTo>
</RewriterRule>
<RewriterRule>
<LookFor>要查找的模式</LookFor>
<SendTo>要用來替換模式的字符串</SendTo>
</RewriterRule>
</Rules>
</RewriterConfig>
httpHandlers的設置主要是配合IIS將請求重新定義處理,這裏也比較關鍵,如果不存在合理的httpHandlers,那麼,訪問肯定會失敗的。
關於正則表達式,可以到百度裏搜索:"常用正則表達式",會有很多。
五.配置IIS解析.html文件
右鍵點我的電腦-->管理-->展開'服務和應用程序'-->internet信息服務-->找到你共享的目錄-->右鍵 點擊屬性 -->點擊'配置'-->映射下面 -->找到.aspx的可執行文件路徑 複製路徑-->粘貼路徑-->擴展名爲".html"-->然後把檢查文件是否存在的勾去掉這樣就可以了,如果遇到“確定”按鈕失效, 可以用鍵盤事件編輯路徑即可解決。
本文實例下載:http://files.cnblogs.com/zhangyi85/StaticWeb.rar
以.aspx\.asp\.php結尾的頁僞靜態爲以.htm或者.html結尾的頁有什麼看法,性能會得到提高嗎,有什麼好處?
那麼或者直接生成靜態頁面又有什麼好處,是否推薦在一個網站大量使用呢?
對於騰訊那樣的大的門戶網站他們的新聞頁是生成的靜態頁呢或者是僞裝的?
最佳答案:
運行PHP,ASP.NET,JSP,ColdFusion的網頁服務器(如IIS,Apache),大多可以用URL Rewriting來實現隱藏或改變拓展名。大網站,象騰訊,百度(用PHP),都在用URL Rewriting的方法來把拓展名隱藏或改變。好處有幾點:
1. 搜索引擎比較喜歡.html,.htm的(與.jsp,.php,.aspx,.cff相比),因爲.html, .htm是靜態的,更容易讓引擎瞭解你網頁的內容。而動態網頁的內容是根據用戶,來輸出不同的內容,不容易讓引擎吸收具體HTML內容。
2. 如果不用URL Rewriting將拓展名隱藏或改成.html,那麼假如這個網站要換個技術或把動態頁面換成靜態,則需要尋找所有含有拓展名的連接,把連接所含URL進行拓展名修改(如從JSP換到PHP技術,則要尋找所有含有.jsp的頁面,並把所有含.jsp的URL改成.php,費時費力)。URL Rewriting正好避免了這點,因爲好的URL是能做到“不變應完變”的。
3. 防止某些黑客惡意攻擊。有些大網站採用不同的技術開發不同功能的頁面。而把拓展名改掉,讓黑客無法確認此頁面用的技術是什麼,從而就無從下手。
4. 方便訪問者使用。訪問者不是程序員,他們不明白什麼是.jsp,.php.aspx,他們只知道URL。所以統一把拓展名拿掉,或者同意把拓展名換爲html,htm,有利於用戶的使用。用戶可以知道現在在你網站的位置,如何通過輸入URL到某一頁面。
實例:
Intelligencia.UrlRewriter.dll aspx重寫爲html實例
1、http://urlrewriter.net/ 下載解壓縮後把Intelligencia.UrlRewriter.dll 文件添加引用到web工程裏。
2.web.config配置:
- <configSections>
- <!--UrlRewriter-->
- <section name="rewriter" requirePermission="false" type="Intelligencia.UrlRewriter.Configuration.RewriterConfigurationSectionHandler, Intelligencia.UrlRewriter" />
- </configSections>
- <system.web>
- <!--UrlRewriter-->
- <httpModules>
- <add type="Intelligencia.UrlRewriter.RewriterHttpModule,Intelligencia.UrlRewriter" name="UrlRewriter" />
- </httpModules>
- </system.web>
- </system.web>
- <!--UrlRewriter-->
- <rewriter>
- <rewrite url="~/test_([a-zA-Z]+).html{1}quot; to="~/Show.aspx?Code=$1" processing="stop" />
- </rewriter>
<configSections>
<!--UrlRewriter-->
<section name="rewriter" requirePermission="false" type="Intelligencia.UrlRewriter.Configuration.RewriterConfigurationSectionHandler, Intelligencia.UrlRewriter" />
</configSections>
<system.web>
<!--UrlRewriter-->
<httpModules>
<add type="Intelligencia.UrlRewriter.RewriterHttpModule,Intelligencia.UrlRewriter" name="UrlRewriter" />
</httpModules>
</system.web>
</system.web>
<!--UrlRewriter-->
<rewriter>
<rewrite url="~/test_([a-zA-Z]+).html{1}quot; to="~/Show.aspx?Code=$1" processing="stop" />
</rewriter>
其中: <rewrite url="~/test_([a-zA-Z]+).html$" to="~/Show.aspx?Code=$1" processing="stop" />
若果code= abc的話,最終顯示的結果爲"虛擬目錄名稱/test_abc.html" 。如果吧.html替換成 .aspx那就是"虛擬目錄名稱/test_abc.aspx"
3.IIS配置:
如果是用"虛擬目錄名稱/test_abc.aspx" 的話,不需要配置IIS. 使用了"虛擬目錄名稱/test_abc.html" 配置IIS的方法如下:
http://urlrewriter.net/index.php/support/installation/windows-server-2003/ 裏面的圖9不準確,準確的爲:
還有第八步中的”untick Verify that file exists.“要看仔細。否則重寫HTML就無效。
4:備註
不要在"應用程序擴展"裏“添加" .html的映射,否則正常的html將無法訪問。
5.在vs2005中,傳多個參數應該加&在vs2003中,只用分號就好了
eg.
- <RewriterConfig>
- <Rules>
- <RewriterRule>
- <!--CreditNews BackGround update-->
- <LookFor>~NewsClsManage-(\d*)-(\d*).html</LookFor>
- <SendTo>~NewsClsManage.aspx?ClassID=$1&flag=$2</SendTo>
- </RewriterRule>
- </Rules>
- </RewriterConfig>
<RewriterConfig>
<Rules>
<RewriterRule>
<!--CreditNews BackGround update-->
<LookFor>~NewsClsManage-(\d*)-(\d*).html</LookFor>
<SendTo>~NewsClsManage.aspx?ClassID=$1&flag=$2</SendTo>
</RewriterRule>
</Rules>
</RewriterConfig>
asp.net僞靜態頁面生成方法 (續二)
<configuration>
<configSections>
<section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
</configSections>
<RewriterConfig>
<Rules>
<!-- Rules for Blog Content Displayer -->
<RewriterRule>
<LookFor>~/read(.[0-9]*)\.html</LookFor>
<SendTo>~/WebForm1.aspx?UserID=$1< ndTo>
</RewriterRule>
</Rules>
</RewriterConfig>
<appSettings>
<add key="dbType" value ="sql"></add>
<add key="data" value="server=.;uid=sa;pwd=sa;database=pubs;Connect Timeout=30;"></add>
</appSettings>
<system.web>
<httpHandlers>
<add verb="*" path="*.aspx" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
<add verb="*" path="*.html" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
</httpHandlers>
這樣好像還不行,那是因爲在IIS裏面無法解析.html後綴名(具體我也不知道怎麼叫...)
然後這樣操作:
右鍵點我的電腦-->管理-->展開'服務和應用程序'-->internet信息服務-->找到你共享的目錄-->右鍵點擊屬性 -->點擊'配置'-->
映射下面 -->找到.aspx的可執行文件路徑 複製路徑-->粘貼路徑-->擴展名爲".html"-->然後把檢查文件是否存在的勾去掉 這樣就可以了