2012年1月21日 星期六

[ASP.NET] 跨瀏覽器禁止使用者返回上一頁 (應用篇)

[ASP.NET] 跨瀏覽器禁止使用者返回上一頁 (討論篇) 中
提到了要達到 Server 端檢查,並禁止返回上一頁,必需透過 Ajax,

簡單地說,便是要以 Call Back 的方式,問 Server 要導向的網頁,
再透過 location.replace('新頁面連結'); 使跳到下一頁時,無法返回上頁,

以下提到了兩種解決方式,
1. 自製 Ajax Button - 彈性較大,適合練習者使用,能加強對 Asp 的熟悉度
2. 利用 Update Panel - 使用簡單,適合應用者使用,只需幾行設定


1. 自製 Ajax Button

使用 Ajax 不難,但麻煩的地方在於,Server 端往往是需要使用者所輸入的資料,
因此,必須將目前所有控制項的值在 Call Back 時也傳到 Server 端,
Server 接到後,還要解析這些參數來做判斷,實在很辛苦

所以我們可以善用既有的資源,
http://www.simonerodriguez.com/ajax-form-submit-example/
這篇清楚提到如何將 submit 以 Call Back 方式完成,
懶得看也沒關係,我們只需用到他取得 Form 中所有控制項的方法

http://dl.dropbox.com/u/27661387/GetQueryString.js
接著再利用 JQuery 提供的 Ajax 方法
$.post(
    theForm.action, 
    getquerystring(theForm), 
    function (result) { eval(result); });
如此便完成了將 Form 內容傳到 Server 端的步驟,
還須處理的問題是,讓 Server 端知道是哪個按鈕所傳的訊息,以做出對應動作,
當然可以直接用 Post 傳參數,但我比較懶,模仿 Asp 的 Post 方法,
直接在 javascript 設定 theForm.__EVENTTARGET.value ,
便可在 Server 端以 Request[" __EVENTTARGET "] 取得
因此,便可知道是哪個控制項所觸發,再做出對應動作,
在此,我是檢查輸入值,若合法則
Response.Write("location.replace('新頁面連結')");
若不合法則
Response.Write("alert('輸入有誤,請重新輸入')");
如此來達到將資料傳回 Server 又禁止返回上一頁之功能,

完整程式碼下載!!

還是嫌麻煩 ~~
很好,懶惰的工程師才能創造最高的工作效率,
下一個方法,便是將以上都包起來了,
準備好了嗎? 眨眼就結束了喔!


2. 利用 Update Panel 

step1. 從工具箱拉 ScriptManager、UpdatePanel,並設定 Button 為 Trigger
step2. 在 Button1_Click,輸入
          ScriptManager.RegisterStartupScript(
                  (System.Web.UI.Page)HttpContext.Current.CurrentHandler,
                  typeof(System.Web.UI.Page), " ", 
                  "location.replace('新頁面連結')", true);
step3. 歡呼!!

其實原理與第一個方法相同,只是解析表單和 Javascript 都由 asp 做掉了
所以實際上要做的就只有幾個步驟,

完整程式碼下載!!


研究了那麼久,終於找到格外簡單的方法解決,
也算在今年的最後一天畫下個完美的句點,
新年快樂囉!!

-----------------------------------------------------------------------------------------------------------------
歡迎與我討論聯繫

[ASP.NET] 跨瀏覽器禁止使用者返回上一頁 (討論篇)

第一篇網誌居然是技術性討論,似乎違反了我的生活哲學,
不過這議題挺有趣的,讓我願意拿它來打頭陣。

在製作問卷網頁時,
常常會希望讓使用者送出資料後無法回到上一頁,
避免一些重複送出的問題...等。

這個問題在不久前我曾經做過,是用最常見的作法,
即在該網頁 Server 端的程式碼加上
Response.Cache.SetCacheability(HttpCacheability.NoCache)
此時每當 Browser 要跟 Server 要求網頁時,
Server 會跟  Browser  說這個網頁不要 Cache,
因此使用者按下上一頁的按鈕時也無法回到上一頁
完成!!

偏偏有天骰子同學跟我說這個方法失效 @@
原來是因為這種方法只適用在 IE,
只有 IE 會接受 Server 提出不要 Cache 的指令
因此便踏上了無止盡的 "Google" 旅程~~

後來發現這問題似乎已被討論許久,
由於在 Browser 按下上一頁的這件事情,是不會跟 Server 要求網頁的,
因此除了像上述方法,事先讓  Browser  知道不要 Cache,否則很難達到該效果
目前尚未知道如何讓 IE 以外的 Browser 不要 Cache,
所以只能從 Javascript 下手了,查到的作法有兩種

1. window.history.forward();      --> 強迫頁面一直導向下一頁
2. location.replace('新頁面連結');  --> 將目前頁面用以新的頁面取代

也是輕鬆完成!!

偏偏客戶沒哪麼好呼嚨 >"<
第一種方法,畫面很 "閃",他不愛
第二種方法,因為想在 Server 端加些判斷來決定是否要跳下一頁,而不知道程式碼該放在哪

方法一算是破局,只好從方法二下手,
在 Button1_Click 事件中加入判斷,成功的話便
Response.Write("<script> location.replace('新頁面連結');</script>");
沒想到案情並不單純,又失敗了,這原因需要從"頭"講起

首先,Browser 跟 Server 要求頁面,Server 會傳頁面的 HTML 讓 Browser 呈現,
此時,Browser 記錄此頁面為 "頁面1" (Page1.aspx),等使用者輸入完成後按下送出,
Server 判斷輸入是合法的值,便傳包含 location.replace('新頁面連結') 的 HTML 給 Browser,
此時,Browser 記錄此頁面為 "頁面2" (Page1.aspx),並執行 location.replace('新頁面連結') 
因此,被取代的頁面是 "頁面2",當使用者按下上一頁時,還是會跳到 "頁面1"
其中關鍵在於每次 Post Back 後所得到的網頁都是獨立的,即使是同樣的 URL 之間也無相關,因此,只要 Post Back 後,一切都來不及了,Browser 已經紀錄 Post Back 前的網頁了,

話說「只有想不到、沒有做不到」,但要做到的代價卻不小,便是透過大名鼎鼎的 Ajax

說到這裡,應該有很多人知道該怎麼做了,
若還想不通,可參考
[ASP.NET] 跨瀏覽器禁止使用者返回上一頁 (應用篇)

最後祝大家新年快樂喔~~