簡體   English   中英

如何阻止瀏覽器后退按鈕重新顯示我的用戶通知?

[英]How can I prevent the browser back button from reshowing my user notification?

我已經為我一直在研究的ASP.NET MVC3站點構建了一個通知系統,讓用戶知道他們執行的各種操作成功發生了(“拍拍背”消息)。 解決方案效果很好,但我有一個問題,我很樂意解決,但我似乎無法解決如何做到這一點。

在控制器中,我有以下示例操作方法:

<HttpGet()>
Public Function Edit(id As Guid) As ActionResult
    Return View(GetMyViewModel(id))
End Function

<HttpPost()>
Public Function Edit(...) As ActionResult
    ' Save updated ... information

    Me.TempData("UserMessage") = "Data Saved! You are truly an awesome user!"

    ' PRG back to Edit
    Return RedirectToAction("Edit")
End Function

然后在我的視圖(剃刀布局)中,我有代碼查找TempData集合中"UserMessage"鍵的存在,如果它存在,我構建了一些JavaScript來為用戶呈現類似於咆哮的通知:

/* This only exists when we have something to show */
$(function () {
    showNotification([the message from TempData]); 
});

然后,類似咆哮的消息要么隨着時間消失,要么用戶可以點擊消息來消除它。

到目前為止一切順利,一切都按預期工作。 用戶POST到Edit ,他們被RPG回到Edit ,咆哮的“ 數據保存!你真是一個真棒用戶! ”消息顯示和解雇。

如果用戶然后導航到另一個頁面,然后點擊瀏覽器的后退按鈕,則瀏覽器會深入到其緩存中,導致瀏覽器執行相同的javascript,向用戶顯示相同的“ 數據已保存!您真是一個非常棒的用戶! ”消息再次。 這讓用戶感到困惑,認為通過單擊后退按鈕,他們只是做了一些導致又一次保存的事情(或者無論消息是什么)。

我正在尋找一種方法,一旦通知顯示一次,我可以以某種方式阻止通知顯示備份 - 基本上使它成為“一次性拍攝”消息。 我想到的是:

  • 包括每條消息的Guid ,並使用localStorage存儲顯示的消息ID列表,並且只有當所請求的消息不存在於顯示的消息列表中時,才顯示它。
    • 我曾經想過以同樣的方式使用Cookie,但是為了將來的請求不必要地將cookie重新發送到服務器,並且需要仔細考慮cookie的內容並且可能無論如何都需要消息,這讓我感到沮喪。 。
  • 而不是從操作方法返回消息,而是返回指向數據庫中的消息的Guid 然后在頁面加載時,AJAX返回服務器以獲取該消息。 獲得消息后,將從數據庫中刪除該消息,通過不返回任何消息來處理對該相同消息的后續請求。
  • 在每條消息中包含一個Guid ,在顯示消息之前,AJAX返回服務器以查看消息是否已經顯示。 顯示消息后,AJAX返回服務器以記錄消息已顯示。

這些對我來說似乎都是站不住腳的,但如果有人想爭論支持其中之一,我可以說服不然。

我嘗試過的事情:

  • 消息被刪除后刪除DOM元素的所有痕跡。
  • 顯示消息時,在消息的DOM元素上設置jQuery .data()屬性以指示消息已顯示,然后在顯示消息之前,確保.data()字段不存在。

這些不起作用,因為瀏覽器在一個時間點緩存頁面,之后發生這兩個DOM更改。

基本上,我需要一個機制,我的javascript可以檢查它是否真的需要顯示這個給定的消息,如果它,顯示它,但然后標記消息如圖所示,如果要求再次顯示它,它沒有。 有什么建議?

您還可以利用瀏覽器記住表單值的事實,簡單示例:

<input id="notification" style="display:none" value="Data Saved!">
<script  type="text/javascript">
$(function () {
    if($('#notification').val())
    {
      alert($('#notification').val());
      $('#notification').val('');
    }
});
</script>

您可以設置cookie以存儲正在顯示的消息的狀態,並在您嘗試顯示消息時檢查cookie是否存在。 如果cookie在那里,你就不會,如果不是,你就可以。
看起來像這樣的邏輯非常簡單,而不是跟蹤GUID :)

// pseudocode
FUNCTION ShowMessage(args)
    // if the cookie is here, don't show the message
    IF StatusCookieIsPresent THEN RETURN

    // if the cookie isn't here, this is the first time showing the message
    ShowStatusMessage()

    // we showed the message, so set the cookie to make sure we don't
    // do it twice
    SetStatusCookie()
END FUNCTION

我不是MVC的專家,但我會盡力幫助你。 我3年前制作了一個Hello World計划,並閱讀了很多相關內容。 :-)你在你的頁面中使用AJAX歷史記錄(在查詢字符串中使用#符號 - 雅虎打破了他們新的YUI郵件框架的功能,或忘記了當你點擊后退按鈕時 - 發送到登錄頁面哈哈)? 當您單擊后退按鈕時,您是來自不同的頁面還是同一頁面來顯示您的消息? 我不太了解Razor框架可以完全幫助你。

起初我以為你可以通過使用這個代碼輕松地在頁面上禁用緩存,但后來我發現你正在使用AJAX,所以這可能不是一個足夠好的解決方案。

<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="0">
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">

這會完全關閉它,但出於性能原因可能不是一個好的解決方案。

<caching>
  <outputCache enableOutputCache="false" />
</caching>

您可以阻止顯示來自您的集合的用戶消息的頁面的緩存,但我不知道您的AJAX中發生了什么以確定。

Response.CacheControl = "No-Cache"

不確定MVC是否會尊重這一點,但值得一試:

Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(false);
Response.Cache.VaryByParams["Category"] = true;

if (Response.Cache.VaryByParams["Category"])
{
   //...
}

或者,也許那個頁面是填充中間的甜甜圈,它太滿了(對於瀏覽器后退按鈕) - 沒有雙關語意圖。 把它變成甜甜圈,它可以解決你的問題。 基本上,您可以實現包含您顯示的消息的視圖控件。 並從此視圖控件中刪除緩存策略。 我想它會在理論上起作用。 希望它在現實生活中適合你。

http://haacked.com/archive/2009/05/12/donut-hole-caching.aspx

OutputCache屬性(在該文章中提到)僅控制給定用戶控件的緩存。

http://msdn.microsoft.com/en-us/library/hdxfb6cy.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM