相信無論是前端還是后端開發(fā)工程師,對于Base64都不會感到陌生,在開發(fā)中我們經(jīng)常會將一些小圖片以Base64的形式存儲和加載。然而知其然也要知其所以然,Base64究竟是什么,我們?yōu)槭裁匆褂肂ase64,以及Base64的優(yōu)缺點(diǎn)又是什么呢?今天我們就來聊一聊。
什么是Base64
首先Base64是一種編碼格式,普遍應(yīng)用于需要在網(wǎng)絡(luò)中存儲和傳輸?shù)亩M(jìn)制數(shù)據(jù)。為什么叫Base64呢,主要是因?yàn)檫@種編碼格式每個字節(jié)的前兩位只能是0,剩下只有6位可以表示,所以對于Base64來說,一個字節(jié)只能表示64種情況。Base64的名字由此而來。
為什么要存在Base64
但我們不難發(fā)現(xiàn),這樣的話這種編碼格式并不能充分利用存儲資源,是比較低效的,那為什么還要用Base64這種編碼呢?為什么不直接傳輸二進(jìn)制而要轉(zhuǎn)成Base64格式再去傳輸呢?
原因是因?yàn)閎ase64最早是用在郵件傳輸協(xié)議中的,當(dāng)時郵件傳輸協(xié)議只支持ascii字符傳遞,ascii碼可以用來表示所有的英文字符和數(shù)字還有一些符號,但其中還存在很多不可見字符或者叫控制字符,不可見字符在傳輸過程中可能會產(chǎn)生一些錯誤,如果郵件中只傳輸英文數(shù)字等,那么ascii是可以直接支持不會有問題,但是如果你要在文件中傳輸一些二進(jìn)制文件,圖片,視頻等資源的時候,不可避免的轉(zhuǎn)成ascii的時候會出現(xiàn)非英文數(shù)字的情況,也就是上面所說的不可見字符,這時就有可能會導(dǎo)致傳輸過程中出現(xiàn)問題。
Base64就是用來解決這個問題的,人們想到把二進(jìn)制劃分為多個3個字節(jié)的塊,把每3個字節(jié)(24位)轉(zhuǎn)換成4個6位,每個六位根據(jù)查表對應(yīng)一個ASCII符號。如下圖所示:
上圖是Base64的編碼字典
如上圖所示,比如我們有一個3個字節(jié)的數(shù)據(jù),轉(zhuǎn)成ascii碼以后就是第一行所示,但我們查詢ascii碼會發(fā)現(xiàn)第三個字節(jié)是個不可見字符,所以如果在曾經(jīng)的郵件傳輸協(xié)議中這么傳輸可能會在過程中產(chǎn)生一些錯誤,于是我們需要轉(zhuǎn)成base64再去傳輸,根據(jù)Base64的轉(zhuǎn)化規(guī)則曾經(jīng)的三個字節(jié)就變成了4組6位的值,然后我們需要在每一組前面補(bǔ)充兩個0補(bǔ)齊字節(jié)長度。于是根據(jù)Base64編碼之后我們打印出的結(jié)果就是S3qb這個字符串。
另外這個例子比較特殊,我們正好是個3字節(jié)數(shù)據(jù),如果1個字節(jié)或者2個字節(jié)時,我們就會發(fā)現(xiàn)位數(shù)不能正好被6整除,不能整除就會是下面這個示例展示的樣子
如何編碼和解碼Base64
在 JAVAScript 中,有兩個函數(shù)被分別用來處理解碼和編碼 base64 字符串。
- btoa() — 字符串轉(zhuǎn) Base64編碼
- atob() — 通過Base64規(guī)則解碼成ascii字符串
使用Base64存儲和加載圖片好不好?
相信大家對于Base64的編解碼和原理已經(jīng)有了深入了解,最后我們簡單聊聊在前端頁面中使用Base64加載圖片到底好不好。所有事情都有兩面性,沒有絕對的好不好,只有在某些特定場景下合不合適。我們來看看Base64加載圖片的優(yōu)劣點(diǎn):
資源大?。焊鶕?jù)我們上面提到的原理,我們很容易發(fā)現(xiàn)Base64會比正常資源要大三分之一,Gzip壓縮之后差距會縮小。
緩存方式:圖片資源很好緩存,但如果是base64的話,如果是在cssjs中引入可以跟文件一起進(jìn)行緩存,如果在html中直接引用則必須緩存html文件,所以緩存方便程度上肯定是圖片資源文件更方便緩存。
加載方式:html/css中引入base64會導(dǎo)致文件體積變大,從而導(dǎo)致首屏展示的比較慢,而用過圖片資源方式異步引入會首屏?xí)故镜谋容^快。但對于需要加載很多圖片的情況下,尤其是腳在很多小圖片小icon的情況下,如果不使用雪碧圖的方式就會造成請求量很大,在http1.1/1.0協(xié)議下,在不開啟keep-alive的情況下,會導(dǎo)致效率低下重復(fù)創(chuàng)建銷毀連接通道,并且瀏覽器存在請求線程限制,并且存在網(wǎng)絡(luò)io延遲,這種情況下base64效率更高,但如果你的應(yīng)用使用http2/3的協(xié)議,base64的優(yōu)勢就不大了。
結(jié)語
所以綜合來看Base64加載圖片的方式多數(shù)情況下并不是最優(yōu)選擇,只有在圖片比較小,比較獨(dú)立并不適合做成雪碧圖的情況下再去使用比較好。