2010-05-19 93 views
4

我試圖讓Opera每次重新請求一個頁面,而不是從緩存中提供它。我發送'Cache-control:no-cache'和'Pragma:no-cache'響應頭文件,但似乎Opera只是忽略了這些頭文件。它可以在其他瀏覽器中正常運行 - Chrome,IE,Firefox。如何停止Opera緩存頁面?

如何從緩存頁面停止Opera?我希望能夠做的是當用戶點擊瀏覽器上的返回按鈕時,Opera重新請求一個頁面。

回答

7

作爲一個用戶,我絕對厭惡那些在使用後退按鈕時通過強制重新加載減慢我的歷史導航的頁面。 (如果您每天使用的瀏覽器注意到各種緩存指令並讓它們以您想要的開發方式影響歷史導航,您可能會注意到一些網站會減慢自己的速度......)

如果你有一個非常強大的用例來做這件事我想說你的架構在某種意義上可能是「錯誤的」,例如,如果你在不斷更新數據的不同「視圖」之間切換,並且因此想要在執行時重新加載用戶回去或許使用Ajaxy技術將不斷變化的數據加載到當前頁面會更好?

Opera的實現是有目的的 - 「緩存」與「歷史導航」在概念上有所不同,前者更多的是將內容存儲在磁盤和會話之間,後者將切換回剛剛訪問的臨時隱藏頁面,在你離開它的狀態下。

但是,如果你確實需要它,那麼這個政策中就有一個漏洞,使得你想要的行爲成爲可能。發送「緩存控制:必須重新驗證」將強制Opera在導航上重新加載每一頁,但如果您通過https發送頁面,則僅限。 (這是偏執銀行所要求的功能,如果應用於http,它會減慢太多正常站點的速度)。

+3

「這是一項針對偏執銀行所要求的功能,如果應用於http,它會減慢太多正常站點的速度」 您是否認爲瀏覽器不應該被真正用於可能有敏感數據的應用程序? :-) – 2010-05-20 14:33:37

+2

如果數據真的很敏感,網站應該使用https。 :-) 由於沒有服務器和瀏覽器共享「會話」的概念,因此網絡規範中存在一個漏洞。如果服務器可以告訴瀏覽器「用戶剛剛註銷/超時,並且我們關閉了會話,請禁止使用後退按鈕查看自會話開始以來的歷史記錄」,我們可以在可用性和安全性之間找到更好的平衡。 – hallvors 2010-05-21 07:34:11

+2

我同意以下兩點:(i)網絡規範中有一個關於「共享會話狀態」的漏洞,(ii)https應該用於真正敏感。但是,「真正的敏感數據」表明數據安全不是數字化的,而是一種模擬的措施。其他瀏覽器通過不允許緩存和必須重新驗證工作來支持這一點,這允許進一步的範圍來管理安全/隱私。 Opera不支持這個 - 對或錯,我不擔心。我需要一個解決方案來解決這種不一致問題。你在歌劇院工作,你能建議什麼? (即腳本,標題等)Thks – Forer 2010-05-21 10:35:53

2

這聽起來像你的問題是關於this answer。在測試您的頭文件和建議的頭文件後,我只能在Internet Explorer中重現您的預期行爲。

+1

我反覆在Opera上重現這個問題。它似乎是唯一不一致的瀏覽器。我已經閱讀了他們嚴格,有原則的處理緩存的方法。但是這實際上只是看起來像一個安全漏洞,沒有做額外的腿部工作。我真的很喜歡一個明確的解決方案,可以實施尼什卡爾的問題。在其他瀏覽器中,頭緩存控件響應頭不能在opera中工作。什麼是工作? – Forer 2010-05-20 14:30:25

0

在搜索解決方案時發現此問題。沒有喜悅,所以寫了一些JavaScript來解決可能被其他人使用的問題。

<HEAD>上述任何其他JavaScript:

<script> 
    if(typeof(opera) != 'undefined') { // only do for Opera 
     if (window.name == 'previously_loaded') { // will be "" before page is loaded 
      alert('Reloading Page from Server'); // for testing 
      window.name = ''; // prevent multiple reload 
      window.location.reload(true); 
     } 
    } 
</script> 

現在改變窗口的名稱,以便歌劇檢測到它在隨後進行的裝載緩存:

window.name = 'previously_loaded'; 

插入這條線在你的js塊的一個習慣在「窗口加載」期間執行,導致無限重新加載。對於我來說,除非有人通過鏈接退出,否則不需要刷新頁面,所以我只是將它添加到我的onclick/onunload函數中。

Before and after demos這裏還有一些筆記。我打算將其添加到我的博客。我只有Opera的幾個遲到版本,所以我希望在演示之前對演示進行一些嘗試,然後再將雞蛋放在我的臉上。

編輯:剛剛意識到,如果稍後訪問的網站更改窗口名稱(它的持久性),那麼背面的標籤重新加載不會發生。只需更改以上陳述即可:

if (window.name != "") { 

在多個選項卡中打開時,Demo工作正常;但我隱約記得窗口名稱應該是唯一的;所以我改變了演示來生成一個獨特的名字。

window.name = new Date().getTime(); 
2

SIMPLE服務器側高速緩存控制,無需標題或FRONTEND SCRIPTS

零依賴,通用語言版


您可以在全球範圍強制重新緩存,而不使用頭通過附加一個md5或sha1校驗和到你的文件名。

這樣它會緩存,如果它是一個完全匹配,否則對待它像一個新的資源。

  • 作品在所有瀏覽器
  • 確認出現嚴格的HTML5 (原來沒有,但是這已經更新。未經檢驗的XHTML,但可能並不適用於該)
  • 不需要額外的頭
  • 保持前端問題和後端問題很好地解耦。
  • 不需要客戶端完整性檢查或源驗證。
  • 凡是可以打印HTML能做到這一點一致,包括靜態內容
  • 如果不是靜態的,易於擴展的運行時間控制到終端用戶(身份驗證,如果需要的話),允許簡單的頁面標誌,以確定精縮,美化或調試源被返回。
  • 將內容服務機制中的客戶端緩存控件完全封裝起來,這使得維護起來非常簡單。
  • 作爲一個方面額外能力,引入了版本客戶端緩存自動推遲到瀏覽器已經高速緩存了校驗和,如果有替換版本,需要單元測試發佈包,以確定它的最小穩定其可以是有用依賴版本什麼的。

  • 你不要永遠不得不擺弄你的瀏覽器來緩存不要再幹擾你的開發過程。

  • 這種方法也可用於版本化的圖像,視頻,音頻,pdf等。幾乎任何作爲靜態數據提供服務的資源都將以類似的方式運行,緩存第一次請求內容,並自動保留進一步考慮文件是否改變。


這是RFC有效的標記。注意腳本和鏈接標籤有一個GET字符串:

?checksum=ba411cafee2f0f702572369da0b765e2

<!doctype html> 

<html lang="en"> 
<head> 
    <meta charset="utf-8"> 

    <title>Client Cache Control Example</title> 
    <meta name="description" content="You're only going to cache this when the content changes, and always when the content changes."> 
    <meta name="author" content="https://stackoverflow.com/users/1288121/mopsyd"> 

    <!-- Example Stylesheet --> 
    <link rel="stylesheet" href="css/styles.css?checksum=ba411cafee2f0f702572369da0b765e2"> 

    <!-- Example Script --> 
    <script src="js/scripts.js?checksum=ba411cafee2f0f702572369da0b765e2"></script> 
</head> 
<body> 
</body> 
</html> 

的GET字符串?checksum=ba411cafee2f0f702572369da0b765e2指的是資源的文件大小的MD5或SHA1哈希值。它可以通過命令行,語言結構或通過將其從Content-Length:標頭的值中散列化來獲得。然後通過將其作爲GET字符串附加到文件名來構造您的hrefsrc屬性。

這個瀏覽器會將它們解釋爲獨立的,並單獨緩存。

如果服務器是靜態資源,服務器將忽略GET參數,但如果它是動態服務的,那麼GET參數將可供解釋語言使用。

這意味着只要在鏈接,哈希值發生變化,瀏覽器會緩存特定版本獨立一次,然後保存,直到永遠,或Expires:的推移,以先到者爲準。

由於校驗和是文件大小的直接反映,因此您可以將Expires:設置爲永久性,並且沒有太大區別。只要該文件更改了一個字節,您仍然會立即看到您的更改。

  • 用你平時做的任何工具生成你的css或js源代碼。

  • 在運行時上文件大小運行一個MD5或SHA1校驗如果是動態服務,並在編譯時如果要生成的靜態內容(如ApiGen文檔,例如)

  • 服務與哈希正常文件附加到文件名的GET字符串(例如:styles.css成爲styles.css?checksum=ba411cafee2f0f702572369da0b765e2

  • 文件中的任何改變強制重新緩存,這意味着你看到真正的價值立即反映出來。

  • 可選,但RAD:這種方式的另外一個好處是,你可以很容易地建立一個開發GET標誌,它將使所有前端源決心美化開發源啓用任何自定義的調試功能,或者用它來解釋版本控制標誌。您可以執行冗餘檢查以確保該標誌只從服務器的已知開發IP地址,代理身份驗證等傳遞,否則,如果您需要安全標誌,則不會執行該標誌。我平時只要有可能與此類似分我的前端源達:

    • 這是它在做什麼活,現在(精縮生產,緩存,默認情況下,?checksum=ba411cafee2f0f702572369da0b765e2)。
    • 這就是現在它應該做的事情,已經足夠美化以供我閱讀(美化產品,never cached,?debug_pretty_source=true)。
    • 這是我用弄清楚什麼是沒有做它應該活到如果在這兩個先前的存在(美化啓用調試,never cached,ACL /白名單授權,?debug_dev_enable=true或類似)。

可以採用同樣的原則使用的版本號,而不是校驗打包發佈,提供你的版本不會改變。校驗和的可讀性較差,但易於自動化並與確切的更改保持同步,但版本後綴對測試程序包穩定性也很有用,前提是版本號反映了不可變的資源。

+0

應該注意的是,http轉接代理有時會使用'GET'來干擾這種情況,這取決於請求到服務器的特定網絡路徑。在這種情況下,可以通過將散列直接附加到文件名而不是使用get字符串,然後使用'.htaccess'重寫規則去除它們,即使在代理干擾的情況下也能工作。這通常不是問題,但有時可能會出現在某些邊緣情況下。例如:'styles.ba411cafee2f0f702572369da0b765e2.css'而不是'styles.css?checksum = ba411cafee2f0f702572369da0b765e2' – mopsyd 2017-11-11 20:42:07