2015-02-17 42 views
2

在我的項目有一個公共文件夾,裏面的腳本:public/worker.js,其中包含一段代碼:爲什麼客戶端不會在公用文件夾中收到此腳本的新版本?

new Worker('worker.js'); 

我啓動流星:

alert('foo'); 

我用一個工人把這個腳本並連接到我的應用程序。 foo被警告。
如果我的public/worker.js代碼更改爲別的:

alert('bar'); 

服務器刷新客戶端,客戶端刷新頁面,但不會得到新的代碼,而不是使用舊的(提醒foo代替新的閃亮bar)。清除緩存然後刷新修復問題。 CTRL+F5沒有解決這個緩存問題,它似乎不適用於這種腳本調用(至少不是我測試過的Firefox版本)。

爲什麼會發生這種情況?
我該如何預防?

回答

2

該腳本被緩存,瀏覽器不會從服務器拉新版本。

我們需要編輯在/workers文件夾中的文件請求的報頭,使用如下代碼的服務器端(我把它包在一個封裝api.use('webapp')):

WebApp.rawConnectHandlers.use('/workers', function(req, res, next) { 
    res.setHeader('cache-control', 'must-revalidate'); 
    next(); 
}); 

使用WebApp.connectHandlers沒有工作,回調從未被調用,所以我用rawConnectHandlers來代替。

我不是100%確定這是最好的方式去,但它的工作原理。

+0

很高興聽到... – 2015-02-18 14:27:26

1

我還沒找到確切的原因,但瀏覽器(至少Chrome)似乎將工作人員腳本與其他Javascript文件以不同方式對待頁面刷新上的緩存,即使從服務器發送的標頭相同。刷新頁面使瀏覽器檢查在腳本標記中引用的新腳本,但不檢查用作工作者的腳本。

我解決這個問題的方法是,在編譯時,我在文件名中包含文件內容的版本號/編譯時間/ md5,因此它最終會變成類似worker.12333.js的文件。這樣做的好處是,如果每個文件名都引用基本上不可變的文件,那麼可以設置遠期過期頭文件...因此,不要告訴瀏覽器永不緩存工作者腳本,它可以永久緩存它。 https://github.com/felthy/grunt-cachebuster就是這樣的一個工具,它可以通過腳本標籤包含Javascript,但也可能有其他工具。

問題在於,必須有一些機制來告訴Javascript更新的文件名,所以它知道要撥打new Worker('worker.12333.js');。我不知道,如果現有可用的工具處理,但我做的方式是隻使用項目生成時間,以秒爲唯一鍵的所有文件

<html build-time="12333"> 
    ... 

,然後通過JavaScript訪問它如此它可以計算出最新的工人腳本文件名。這並不完美,但相當簡單。您可能會根據您的要求提出其他機制。

+0

「對工作人員腳本的處理方式與其他Javascript文件的不同之處在於刷新頁面時緩存」您是什麼意思?即使使用下面的解決方案,Chrome將永遠不會正確地重新加載腳本? – 2015-09-22 08:47:00

+0

@Kyll我編輯了我的答案,說明有什麼不同。 – 2015-09-22 09:49:00

+0

有趣。這可能是Chrome的一個bug,可能會向他們報告? – 2015-09-22 11:30:34