2009-06-05 128 views
4

我們使用具有JsonP機制的動態腳本標記來實現跨域Ajax調用。前端小部件非常簡單。它只是調用搜索Web服務,傳遞用戶提供的搜索條件並接收並動態呈現結果。如何防止IE緩存導致重複的Ajax請求?

注意 - 對於那些不熟悉的動態腳本標籤與執行類似Ajax的請求到服務的JSONP方法返回JSON格式的數據,我可以解釋如何利用它,如果你認爲它可能與問題有關。

該服務是WCF託管在IIS上。這是Restful,所以當用戶點擊搜索時我們做的第一件事就是生成一個包含條件的Url。它看起來像這樣...

https://.../service.svc?criteria=john+smith

然後,我們使用動態創建的HTML腳本代碼設置到上述網址的來源屬性,使要求我們的服務。結果返回,我們處理它以顯示結果。

這一切工作正常,但我們注意到,當使用IE服務收到來自客戶端的請求兩次。我用小提琴手來監視流量離開瀏覽器果然我看到兩個請求與以下網址...

第二個請求已附加了某種Id。每個請求的Id都不相同。

我的直接想法是它與緩存有關。在網址末尾添加隨機數是禁用瀏覽器緩存的經典方法之一。爲了證明這一點,我調整了IE中的緩存設置。

  • 我將「檢查更新版本的存儲頁面」設置爲「從不」 - 這導致每次只產生一個請求。結尾有隨機數的那個。

  • 我將此設置值重新設置爲默認值「自動」,並且請求立即開始再次發送兩次。

有趣的是,我沒有收到客戶的兩個請求。我發現這reference有人建議這可能是一個與IE瀏覽器的錯誤。 Firefox上這種情況不會發生,這一事實支持這一理論。

  1. 任何人都可以確認這是否與IE瀏覽器的錯誤?這可能是設計。
  2. 有誰知道我可以阻止它發生的一種方式嗎?

我的用戶運行的一些比較模糊的搜索佔用了足夠的處理資源,使任何一個非常糟糕的想法翻倍。我真的想避免這種情況,如果在所有可能:-)

回答

2

我最終確定了重複請求的原因。正如我所說,我選擇用於進行Ajax調用的機制是使用動態腳本標記。我建立請求的URL,創造了一個新的腳本元素和分配的URL src屬性...

var script = document.createElement(「script」); 
script.src = https://....」; 

然後通過其追加到文件頭部執行腳本。重要的是,我是使用jQuery附加功能......

$(「head」).append(script); 

裏面的附加功能:jQuery是期待,我試圖讓Ajax調用。如果要附加的元素類型是腳本,則它執行一個特殊的例程,該例程使用XmlHttpRequest對象發出Ajax請求。但腳本仍然被追加到文檔頭上,並由瀏覽器在那裏執行。因此,雙重要求。

  1. 第一個直接來自劇本 - 我打算髮生的一個。
  2. 第二個來自JQuery附加函數。這是後綴爲「& _ = 123456789」形式的隨機生成的查詢字符串參數的請求。

我通過防止JQuery庫的副作用來簡化事情。我使用本機追加功能...

document.getElementByTagName(「head」).appendChild(script); 

現在發生一個請求以我想要的方式發生。我不知道JQuery append函數可能會產生如此明顯的副作用。

3

我剛寫了一篇文章如何avoid caching of ajax requests :-)

它基本上包括添加沒有緩存頭隨附在

任何Ajax請求
public abstract class MyWebApplication : HttpApplication 
{ 
    protected MyWebApplication() 
    { 
     this.BeginRequest += new EventHandler(MyWebApplication_BeginRequest); 
    } 

    void MyWebApplication_BeginRequest(object sender, EventArgs e) 
    { 
     string requestedWith = this.Request.Headers["x-requested-with"]; 
     if (!string.IsNullOrEmpty(requestedWith) && requestedWith.Equals(」XMLHttpRequest」, StringComparison.InvariantCultureIgnoreCase)) 
     { 
      this.Response.Expires = 0; 
      this.Response.ExpiresAbsolute = DateTime.Now.AddDays(-1); 
      this.Response.AddHeader(」pragma」, 「no-cache」); 
      this.Response.AddHeader(」cache-control」, 「private」); 
      this.Response.CacheControl = 「no-cache」; 
     } 
    } 
} 
+0

對於我來說,看起來像是一個非常好的開始。如果事實證明有幫助,我會盡快接受。感謝您及時的回覆! – 2009-06-05 15:16:50

0

請參閱www.enhanceie.com/redir/?id=httpperf進一步討論。