日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

重提URL Rewrite(3):在URL Rewrite后保持PostBack地址(转老赵blog)

發布時間:2024/9/20 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 重提URL Rewrite(3):在URL Rewrite后保持PostBack地址(转老赵blog) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在進行了URL Rewrite之后,經常會遇到的問題就是頁面中PostBack的目標地址并非客戶端請求的地址,而是URL Rewrite之后的地址。以上一篇文章中的重寫為例:

<rewriter>
? <rewrite url="^/User/(\d+)$" to="~/User.aspx?id=$1" processing="stop" />
? <rewrite url="^/User/(\w+)$" to="~/User.aspx?name=$1" processing="stop" />
</rewriter>

當用戶請求“/User/jeffz”之后,頁面中的出現的代碼卻會是<form action="/User.aspx?name=jeffz" />,這是因為在生成代碼時,頁面會使用當前Request.Url.PathAndQuery的值來得到form元素的action。這導致了一旦PostBack,地址欄里就會出現“User.aspx?name=jeffz”,而這個地址很可能是請求不到正確的資源的(因為可能被Rewrite到了別處,或者由于目錄級別的關系而根本沒有該資源)。在之前《UpdatePanel與UrlRewrite》一文中,我說可以在頁面末尾添加一行JavaScript代碼來解決這個問題:

<script language="javascript" type="text/javascript">
??? document.getElementsByTagName("form")[0].action = window.location;
</script>

這行代碼的意圖非常明顯,將form的action修改為window.location(即瀏覽器地址欄中的路徑),這樣當頁面進行PostBack時,目標地址就會是URL Rewrite之前的地址了。這種做法能夠讓程序正常運行,但是實在不能讓我滿意。為什么?

因為太丑了。

因為我們還是把URL Rewrite之后的地址暴露給了客戶端。用戶只要裝一個TextWriter writer)
??????? {
??????????? base.Render(new RewriteFormHtmlTextWriter(writer));
??????? }
??? }
?
??? public class RewriteFormHtmlTextWriter : HtmlTextWriter
??? {
??????? public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
??????????? : base(writer)
??????? {
??????????? this.InnerWriter = writer.InnerWriter;
??????? }
?
??????? public RewriteFormHtmlTextWriter(TextWriter writer)
??????????? : base(writer)
??????? {
??????????? this.InnerWriter = writer;
??????? }
?
??????? public override void WriteAttribute(string name, string value, bool fEncode)
??????? {
??????????? if (name == "action")
??????????? {
??????????????? Controls.HtmlForm"
?????????????? adapterType="Sample.Web.UI.Adapters.FormRewriterControlAdapter" />
??? </controlAdapters>
? </browser>
</browsers>

至此,在ASP.NET層面上作URL Rewrite導致PostBack地址改變的問題已經完美解決了——等等,為什么要強調“ASP.NET層面”?沒錯,因為如果在IIS層面上作URL Rewrite,這個問題依舊存在。例如您使用了IIRF做URL Rewrite,并讓上面的Control Adapter生效,還是會發現頁面上PostBack的地址和客戶端請求的地址不同。難道RawUrl也變得“不忠誠”了?這不是RawUrl的緣故,而是ASP.NET機制所決定的。為了解釋這個問題,我們重新看一下在第一篇文章《IIS與ASP.NET》中那幅示意圖:

IIS級別的URL Rewrite發生在上面這幅圖中步驟2之前,正因為被重新Rewrite了,所以IIS的ISAPI選擇器才會將該請求交給ASPNET ISAPI處理。換句話說,當IIS把請求交由ASP.NET引擎處理的時候,ASP.NET從IIS那里獲得的信息中已經是URL Rewrite之后的地址了(例如/User.aspx?name=jeffz),這樣無論在ASP.NET處理該請求的哪個環節,都無法得知IIS當初收到請求時的URL。

也就是說,其實真沒辦法了。

不過“真沒辦法”四個字是有條件的,完整地說應該是:“靠ASP.NET自身”的確“真沒辦法”了。不過如果IIS在進行URL Rewrite的時候幫我們一把,那么情況又會如何呢?IIRF作為一個成熟的開源組件,它自然知道ASP.NET引擎,乃至所有的ISAPI處理程序都需要它的幫助,它自然知道“改出手時就出手”的道理,因此它練就了將原始地址存放在服務器變量HTTP_X_REWRITE_URL之中的能力。不過IIRF也不會“自覺”地這么做(多累啊),這還要我們在配置文件中提醒它:

RewriteRule??? ^/User/(\d+)$??? /User.aspx?id=$1????? [I, L, U]
RewriteRule??? ^/User/(\w+)$??? /User.aspx?name=$1??? [I, L, U]

請注意,我們使用了額外的Modifier。在Modifier集合中加入U表明我們需要IIRF將URL Rewrite之前的原始地址存放在服務器變量HTTP_X_REWRITE_URL中?,F在我們就可以在ASP.NET獲取到這個值了,于是我們將之前的Control Adapter代碼中的WriteAttribute方法作如下修改:

public override void WriteAttribute(string name, string value, bool fEncode)
{
??? if (name == "action")
??? {
??????? HttpContext context = HttpContext.Current;
?
??????? if (context.Items["ActionAlreadyWritten"] == null)
??????? {
??????????? value = context.Request.ServerVariables["HTTP_X_REWRITE_URL"]
??????????????? ?? context.Request.RawUrl;
??????????? context.Items["ActionAlreadyWritten"] = true;
??????? }
??? }
?
??? base.WriteAttribute(name, value, fEncode);
}

現在action的value已經不是簡單地從RawUrl屬性中獲取了,而是設法從ServerVariables集合中取得HTTP_X_REWRITE_URL變量的值,因為那里存放了IIS所接受到的原始請求的地址。

至此,有關URL Rewrite的主要話題已經講完了,在下一篇,也就是本系列的最后一篇文章中,我們將重點看一下使用不同層面的URL Rewrite會在一些細節方面造成什么樣的區別,以及相關的注意點。

轉載于:https://www.cnblogs.com/webdesign/archive/2011/01/20/tt49.html

總結

以上是生活随笔為你收集整理的重提URL Rewrite(3):在URL Rewrite后保持PostBack地址(转老赵blog)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。