靜態資源部署問題的一些思考

2021-08-30 17:31:01 字數 2727 閱讀 5502

當我還是乙個初入門的小前端時,對靜態資源的引用方式就是理解為在html**裡面,通過乙個link或者script標籤,寫乙個相對或者絕對路徑,去拿到對應的靜態資源。比如下面這樣:

沒有什麼毛病,一切都是那麼美好,開啟瀏覽器檢視network,發現狀態碼是200。

但是問題在於,使用者在訪問頁面的時候都要去載入一次這個資源,那其實是不太好的,前端的瓶頸在於頻寬,我們需要盡量節約請求數,所以很多時候,我們需要瀏覽器的快取機制,可以利用http1.0中的expires或者1.1中的max-age,給響應頭寫上標記,這樣一來,我們下次再來訪問這個頁面的時候,檢視這個請求,狀態碼應該還是200,但是這次是from cache,我們直接從瀏覽器的快取那裡拿到了這個靜態資源檔案。

或者還可以利用not modified 這個標記,這樣子當瀏覽器不確定這個資源是否真的過期時,就可以通過協商快取機制來詢問伺服器,假如檔案並沒有被更新,將會告知瀏覽器繼續使用該資源,響應頭狀態碼變為304。

當我的資源內容改變時,此時怎麼辦呢,要怎麼讓瀏覽器去獲取到最新的檔案呢?也許你會說,在url後面加上字尾不就可以了麼?

但是這種方式很低效,並且在有多個引用時就變得很繁瑣。而且,以這種遞增版本號作為字尾的方式不是很科學,為什麼?假如這個檔案的內容實際上並沒有改變,但是你還是改動了這個version,那你又讓瀏覽器重新去發起請求抓取最新檔案了,浪費了快取,所以比較好的方法是,根據檔案內容做乙個摘要,把這個摘要作為檔案的字尾,可能就像下面那樣

這樣子的話,只有當檔案內容確實改變時,我們的瀏覽器才會發起請求抓取最新的資源。

或者還有人使用的是在獲取資源時,在後面加上時間戳,這樣確實可以每一次都獲取到最新的資源,但是這麼一來,就無法利用快取了。

現在有點規模的公司,都會把靜態資源部署到cdn上,而不是直接丟到提供服務的機器上,cdn的好處不言而喻,但是當這些資源抽離出來被放到了cdn上後,又有乙個新的問題了,就以上面的場景來說:舉個例子,比如某個時刻,後端的頁面結構發生了改變,同時,對應的css檔案和js檔案也發生了改變,這時候需要發布上線了,那麼我們是先發前端應用還是先發後端應用呢?

其實以上說的可以看出,倆種方式都是有點問題的。

再說上述問題的答案之前,先提乙個關鍵點,就是我們發布前端資源的姿勢。大致可以分為增量部署和覆蓋式部署。前者可以看成是在機器上多了乙個版本的檔案,而後者則是覆蓋掉原來的檔案。我們可以根據前端應用的某個標誌。比如package.json的version來控制是否是增量發布,比如你改動了kasol.css,但是不改version,他原先的版本號是1.0.0,那麼發布的時候,那麼他就會在1.0.0這個資料夾下把原先的資源給覆蓋了,同理,假如改動了kasol.css,並且版本號公升級為了1.0.1,那麼發布的時候,會在1.0.1這個資料夾下生成資源,不會去覆蓋1.0.0這個資料夾。

那麼比較好的做法是怎麼樣的呢?

首先我們利用構建工具生產出來的靜態資源檔案應該是這樣的姿勢

kasol.ae2sk2o.css
然後在頁面上,自然是去這樣引用

區別在哪呢,可以看到,那個摘要的值從字尾移動到了檔案的副檔名中。這樣當後端的頁面去獲取資源的時候,只要這個摘要不同,抓取的資源就是不一樣的。

但是第三點中提到的,不管先部署哪一種應用貌似都會有問題,不過現在看來。我們可以先部署前端靜態資源,再部署後端應用。為什麼這麼說呢?舉個覆蓋式部署的例子:

原先舊版本的頁面結構是這樣

cdn上的靜態資源是這樣

現在靜態資源改變了,變成了下面這樣

雖然後端沒有什麼邏輯更改,但是我們需要改變後端的引用:

可能有人會說,按照上述的邏輯,使用者在時間間隔內假如去訪問舊的頁面,由於後端的引用沒有更新,那麼抓取的還是 ,由於是覆蓋式部署,此時已經被新的覆蓋掉了,是不是應該404了?

其實仔細觀察上述靜態資源就會發現,除了副檔名中的部分hash值不同,其他都是一樣的。所以要是後端應用可以自動感知到新的hash並應用,那就好了。

所以我們可以這樣來處理,前端構建完靜態資源後,生成乙個map,也丟到cdn上去,本質上就是類似乙個json物件,比如名字叫1.0.0.map,他大概長這樣。

當更新完靜態資源,map也會變化,比如這樣

這個map也是跟著版本號走的,對於不同的版本號,都有各自的map。

然後我們在後端應用部署乙個sdk,他的作用就是輪詢去獲取對應版本前端資源的map物件,然後在模板中把靜態資源的hash值丟進去,這樣一來,實際上假如後端應用本身沒有邏輯更改,就不需要去發布後端應用,只要發布前端應用即可。等發布完成之後,後端模板會自動去獲取最近的資源。

再來說說增量式發布,這種情況大多是後端也改了一些dom結構,所以此時後端應用也是需要發布的。還是以先部署前端應用來說:首先kasol.ksoplw.cssb並不會把之前kasol.ae2sk2o.css給覆蓋掉,而是多了這乙個帶hash物理檔案。

接著在後端未部署完成的時間間隔內,使用者訪問舊的頁面,此時後端的sdk通過輪詢拿的還是舊版本的map,所以還是抓取舊版本的資源,即,舊的頁面配上舊的靜態資源,沒什麼問題。然後當後端也部署完成後,後端sdk拿到新的map,將新的hash值放到頁面裡去,新的頁面結構會去抓取,此時就可以擊穿快取,去cdn上拿到新的靜態資源。

基於Django靜態資源部署404的解決方法

一.靜態資源static檔案放在app中 確認django.contrib.staticfiles包含在installed apps中。在settings檔案中定義static url,例如 static url static 在模板中,可以硬編碼url如 static my app example...

spring boot關於靜態資源的一些問題

每次新建乙個專案都會為訪問不到靜態資源煩惱,以下記錄訪問靜態資源的一些問題 使用spring boot專案是一般會使用thymeleaf模板來獲取資料,所以必須要匯入thymeleaf的座標 org.springframework.boot spring boot starter thymeleaf...

關於SpringMVC訪問靜態資源的一些個人見解

昨晚臨回宿舍之前遇到乙個訪問靜態資源路徑的問題,研究了一會兒,沒有研究出來。今天一早開啟電腦,螢幕是昨天遺留的問題,越看越想解決它,要不然心裡很不舒服。沒想到這一深入研究,挖掘出以前許多和這相關但沒注意的知識,結果陷入進去了,本來是乙個問題,但逐漸轉變成一小塊知識的問題,就這樣逐漸摸索和排盲,白天的...