做過網站或WEB系統的,肯定都曾在自己的頁面中用過“傳回”按鈕。我也不例外,在多次的開發中,我曾經思索:這個小小的“傳回”按鈕,應該以怎樣的代碼實作比較好。
先說說自己最常使用的,也是最常見最無腦的。如:
1 protected void Back()
2 {
3 Response.Redirect("CurrList.aspx");
4 }
有時候,當傳回的頁面的是一個帶分頁的頁面時,則需要在進入頁面時傳入分頁資訊,然後在傳回時取出這些值。比如:
1 private void Goback()
2 {
3 string size = Request.QueryString["size"];
4 string index = Request.QueryString["index"];
5 Response.Redirect("SellInfoDisplay.aspx?size=" + size + "&index=" + index );
6 }
用的最多的,無非以上了。
有的時候,再複雜一些,比如一個頁面可以從不同的頁面跳入,那麼,還得再記錄哪個頁面來的,傳回的時候,再判斷判斷。
再有的時候,A頁面跳到B頁面,B頁面再跳到C頁面,這個時候想要連着兩次傳回到A頁面,要寫的代碼就多了。
那麼,這個小小的“傳回”按鈕有沒有什麼好的方法去處理呢?
首先我嘗試了這樣的方法:
1 history.go(-1);
曾經在某些頁面中用過這樣的方法,似乎也沒什麼問題。但這個方法是有使用範圍限制的,通常它适合用在靜态頁面。另外,當跳轉之前頁面執行了某個腳本,而這個腳本中alert了一下,此時用這個方法跳轉回來的時候,我發現它又alert了一下,這顯然不行。
接着我又嘗試了這樣的方法:
1 protected void SaveCurrURL()
2 {
3 Session["prevURL"] = Request.UrlReferrer.PathAndQuery;
4 }
5
6 protected string GetCurrURL()
7 {
8 return Session["prevURL"].ToString();
9 }
10
11 protected void Back()
12 {
13 Response.Redirect(this.GetCurrURL());
14 }
前兩個方法寫在自定義的頁面基類中,并且我約定了系統中總是将分頁,查詢,排序等參數資訊儲存在URL中。接着我制作了對應的分頁控件,正當我沾沾自喜,以為大功告成的時候,又一個問題出現了。
Request .UrlReferrer .PathAndQuery 這句代碼似乎會有失靈的時候。
經過幾次嘗試,發現問題是這樣的:
假設從A頁面跳轉至B頁面,那麼A頁面的方式如果是以腳本的方式進行跳轉的話,那麼在B頁面調用SaveCurrURL方法是擷取不到預期的值的,比如(location.href=。。。。),而在A頁面以超連結的方式進行跳轉的話,則可以順利擷取到。
這是何故?又怎麽辦呢?我們知道,使用者點選超連結屬于使用者主動行為,而腳本觸發,則屬于被動行為,有時候某些被動行為會因為安全方面的考慮而受到重重阻礙。我們可以以腳本的方式觸發超連結元素的onclick事件,确很難模拟使用者直接點選超連結的效果(我認為是不能)。
後來我決定退一步,犧牲一下性能,将代碼改成Session["prevURL"] = Request.Url.PathAndQuery;
并且為了支援兩級的傳回,最後的代碼是這樣的
1 protected void SaveCurrURL(bool first)
3 if (Session["prevURL"] == null)
4 Session["prevURL"] = new string[3];
5 string[] urls = (string[])Session["prevURL"];
6 if (first)
7 {
8 urls[0] = Request.Url.PathAndQuery;
9 urls[1] = null;
10 urls[2] = null;
11 }
12 else
13 {
14 if (urls[1] == null)
15 urls[1] = Request.Url.PathAndQuery;
16 else
17 urls[2] = Request.Url.PathAndQuery;
18 }
19 Session["prevURL"] = urls;
20 }
21 ///<summary>
22 /// 擷取上次儲存的URL23 ///</summary>
24 ///<returns></returns>
25 protected string GetCurrURL()
26 {
27 string[] urls = (string[])Session["prevURL"];
28 for (int i = 2; i >= 0; i--)
29 {
30 if (urls[i] != null)
31 {
32 string url = urls[i-1];
33 urls[i] = null;
34 urls[i - 1] = null;
35 Session["prevURL"] = urls;
36 return url;
37 }
38 }
39 throw new Exception("");
40 }
最終的代碼費了我不少心思,為了使session保持小巧,我用了string數組,而不是string list,為了支援兩級傳回,我将數組的長度設為3,這是有原因的。
它們是這樣的使用方式,假設有A\B\C 3個頁面,
A可以跳到B,B可以跳到C,C可以傳回B,B可以傳回A。
那麼在A頁面,這是一個起點頁面,調用SaveCurrURL傳入TRUE參數,B和C頁面的參數為FALSE,注意C頁面也要調用,這屬于一個瑕疵。
在B和C的傳回按鈕中,不論他們是不是從A跳過來的,也不論他們處與第2個頁面還是第3個頁面,統統調用
Response.Redirect(this.GetCurrURL ());
最後,别忘了在if (!IsPostBack)中調用Save函數.
以上便是我對“傳回”功能的小小嘗試,隻能說支援一定的使用範圍,有一定的簡化作用和通用的處理方式。當然它沒有經過嚴格的測試,也希望大牛們能提供更好的方案。
<b>修改了一下:</b>
12 else13 {
16 else if (urls[2] == null)
18 else
19 urls[2] = null;
20 }
21 Session["prevURL"] = urls;
22 }
23 ///<summary>
24 /// 擷取上次儲存的URL
25 ///</summary>
26 ///<returns></returns>
27 protected string GetCurrURL()
28 {
29 string[] urls = (string[])Session["prevURL"];
30 for (int i = 2; i >= 0; i--)
31 {
32 if (urls[i] != null)
33 {
34 string url = urls[i-1];
URL儲存和擷取方法都稍微了改了一下。
現在在有傳回按鈕的頁面上這樣用:
1 this.SaveCurrURL(false );
2 lbBack.NavigateUrl = this.GetCurrURL();
本文轉自 wws5201985 51CTO部落格,原文連結:http://blog.51cto.com/wws5201985/735603,如需轉載請自行聯系原作者