http協議中比較重要的幾個頭

lixiange發表於2019-10-05

Babel可以將es6中的高階語法轉化成es5中的低階語法,需要安裝

@babel/cli 用來解析core

@babel/core

@babel/preset-env 將es6-àes5

壓縮

在專案優化中有兩個比較重要的頭,快取和壓縮

首先客戶端要支援壓縮:Accept-Encodeing:gzip deflate br

伺服器要判斷一下瀏覽器是否支援壓縮,支援的是那種壓縮

let encoding=req.headers[‘accept-encoding’]

if(eccoding){

用的是正則,判斷是否有gzip格式

if(encoding.match(/gzip/)){

壓縮之前要返回一個頭,告訴瀏覽器是使用哪種方式壓縮的,編於瀏覽器解析

Res.setHeader(“Content-Encoding”,”gzip)

Return zlib.createGzip()

gzip(filePath,req,res,statObj){

​ //看一下瀏覽器是否支援壓縮,支援的是那種壓縮

​ let encoding=req.headers['accept-encoding']

​ //如果accept-encoding中有gzip

​ if(encoding){

​ //壓縮之前要先返回一個頭,告訴瀏覽器使用那種方式壓縮的,以便瀏覽器解析,不設定頭會出現亂碼

​ if(encoding.match(/gzip/)){

​ res.setHeader("Content -Encoding","gzip")

​ return zlib.createGzip()

​ }else if(encoding.match(/deflate/)){

​ res.setHeader("Content-Encoding","deflate")

​ return zlib.createDeflate()

​ }

​ return false

​ }

​ return false}

在返回檔案之前先通過一個管道進行壓縮

let flag=this.gzip(filePath,req,res,statobj)

let flag= this.gzip(filePath,req,res,statObj)

​ //在響應資料之前設定一個頭 res.setHeader('ContentType',mime.getType(filePath)+"; charset=utf8")

​ //node中流非常重要

​ if(flag){

​ fs.createReadStream(filePath).pipe(flag).pipe(res)

​ }else{

​ //客戶端不支援壓縮,或者客戶端支援的壓縮格式伺服器滿足不了

​ fs.createReadStream(filePath).pipe(res)

​ }

快取

強制快取,需要伺服器設定一個響應頭

res.setHeader('Cache-Control','max-age=20')

設定強制快取後,在規定的時間內不會走快取

res.setHeader('Cache-Control','no-cache')走網路,但有快取

res.setHeader('Cache-Control','no-store')走網路,沒有快取

對比快取,也叫協商快取

let lastModified=statObj.ctime.toGMTString()

let ifModifiedSince=req.headers['if-modified-since']

設定一個響應頭,告訴瀏覽器最新修改的時間,如果檔案改動了瀏覽器會用Last-Modified來作為最後的修改時間,在下一次訪問伺服器的時候作為請求頭帶過去

res.setHeader('Last-Modified',statObj.ctime.toGMTString())

如果檔案修改了,就會自動新增一個請求頭,If-Modified-Since,表示瀏覽器上快取頁面的最後修改時間

如果時間一致,那麼返回HTTP狀態碼304(不返回檔案內容),客戶端接到之後,就直接把本地快取檔案顯示到瀏覽器中。

如果時間不一致,就返回HTTP狀態碼200和新的檔案內容,客戶端接到之後,會丟棄舊檔案,把新檔案快取起來,並顯示到瀏覽器中

 if(ifModifiedSince){

​             if(ifModifiedSince !== lastModified){

​                 // 修改了檔案  走網路

​                 return false

​             }

​            return true

​        }
複製程式碼

對比快取有一定的不足,當修改了內容之後恢復原來的內容,ifModifiedSince和lastModified還是不一樣,依然會走網路

利用摘要做快取

摘要演算法:不可逆,長度是固定,相同的內容摘要相同,不同的內容摘要不同

引入crypto內建中介軟體,

let Etag=crypto.createHash('md5').update(fs.readFileSync(filePath)).digest('base64')

let ifNoneMatch=req.headers['if-none-match']

//if-none-match當你修改伺服器上的檔案時,請求頭上面會自動新增這個頭

res.setHeader('Etag',Etag)

//Etag是根據摘要來判斷是否快取

//Etag是根據摘要來判斷是否快取

        if(ifNoneMatch){

​             //說明內容被修改了

​             if(ifNoneMatch !==Etag){

​                 //修改了內容,並且沒恢復,走網路

​                 return false;

​            }else{

​                //修改了內容,並且修改完後,把內容恢復,相當於沒有修改

​                 return true //還是從快取中取資料

​             }

​         }else{

​             //說明內容沒有改變

​             return true

​         }
複製程式碼

利用對比快取和利用摘要做快取的程式碼優化

if(ifModifiedSince&&ifNoneMatch){

​            if(ifNoneMatch !==Etag && ifModifiedSince !== lastModified){

​                return false

​            }

​        }else{

​            return false

​        }

​        return true       

​    }
複製程式碼

Content-Type 告訴客戶端返回檔案的型別

可以動態新增檔案的型別

通過一個包mime

mime.getType(filePath)可以將檔案自動轉化為對應的檔案型別

res.setHeader('Content-Type',mime.getType(filePath)+";charset=utf8")

User-Agent 在pc端和移動端輸入同一個地址http://www.taobao.com,會出現兩套不一樣的專案

訪問時會自動新增一個請求頭User-Agent

HTTP中的頭: 請求頭: accept-encoding 告訴伺服器,我接收的資料支援壓縮格式

​ if-modified-since: 對比快取 修改時間 ​ if-none-match: 摘要快取 和Etag配對使用的

​ 響應頭: ​ Content-Type 告訴瀏覽器 我給你的內容的型別 ​ Content-Encoding 告訴瀏覽器 我給你的內容的壓縮格式

​ Cache-Control 強緩 告訴瀏覽器,你多長時間之間,不要來訪問我 ​ Expires 強緩 告訴瀏覽器,你多長時間之間,不要來訪問我

​ Last-Modified: 對比快取 和 if-modified-since 配對使用 ​ Etag 根據摘要做快取 和 if-none-match 配對使用

相關文章