1、前言 javascript
上週五公司內部的Any Topic Conf.上我和同事們分享了這個主題,有同事說這個有用,有同事說這個沒啥用,後來還延伸到網站性能的話題上,你們討論的激烈程度讓我以爲此次選題還不錯。本篇先無論到底有用與否,僅僅記錄理論知識。也但願你們一塊兒來分享實戰經驗啊!php
2、從HTTP URI Scheme入手 css
對於 <a href="http://github.com">HTTP URI Scheme</a> 我想你們都應該很熟悉了,href屬性值http://github.com就是HTTP URI Scheme,那麼什麼是DATA URI Scheme呢?其實就是形如data:text/jpeg;base64,XINGSXXIANGJIJIGSAG==的資源連接,通常出如今img元素的src屬性。html
DATA URI Scheme的做用,通常就是將通過Base64編碼的數據嵌入網頁中,從而減小請求資源的連接數。上面的DATA URI Scheme中 base64, 後的字符就是通過base64編碼後的數據,瀏覽器會對其解碼並渲染該圖片資源。java
3、Data URI Scheme格式 git
data:①[<mime type>]②[;charset=<charset>]③[;<encoding>]④,<encoded data>⑤github
①. data :協議名稱;數組
②. [<mime type>] :可選項,數據類型(image/png、text/plain等)瀏覽器
③. [;charset=<charset>] :可選項,源文本的字符集編碼方式緩存
④. [;<encoding>] :數據編碼方式(默認US-ASCII,BASE64兩種)
⑤. ,<encoded data> :編碼後的數據
注意:
[a]. [<mime type>][;charset=<charset>] 的缺省值爲HTTP Header 中Content-Type的字段值;
[b]. [;<encoding>] 的默認值爲US-ASCII,就是每一個字符會編碼爲%xx的形式;
[c]. [;charset=<charset>] 對於IE是無效的,須要經過 charset 設置編碼方式;而Chrome則是 charset 屬性設置編碼無效,要經過 [;charset=<charset>] 來設置;FF就兩種方式都可。
[d]. 若 ,<encoded data> 不是以 [;<encoding>] 方式編碼後的數據,則會報異常
4、示例
/** * data:,文本數據 * data:text/plain,文本數據 * data:text/html,HTML代碼 * data:text/css;base64,css代碼 * data:text/javascript;base64,javascript代碼 * data:image/x-icon;base64,base64編碼的icon圖片數據 * data:image/gif;base64,base64編碼的gif圖片數據 * data:image/png;base64,base64編碼的png圖片數據 * data:image/jpeg;base64,base64編碼的jpeg圖片數據,示例: */ body { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC");} /** * data:text/css,css代碼,示例: * 注意:下列方式是沒法設置background-image:url()樣式的 */ <link rel="stylesheet" type="text/css" href="data:text/css;charset=gbk,#pseudo{color:red;}"/> //data:text/javascript,javascript代碼,示例: <script type="text/javascript" charset="gbk" src="data:text/javascript;charset=gbk,alert('%D6%D0%CE%C4')"></script>
5、優勢&缺點
優勢:
①. 減小資源請求連接數。
缺點:
6、優化方案
經過在css文件的background-image樣式規則使用Data URI Scheme,使其隨css文件一同被瀏覽器緩存起來。
7、瀏覽器支持
8、標籤支持
嵌入圖片的object、img、input[type=image]、script、link和css規則中的background和backgroundImage屬性
9、IE678的polyfill方案——MHTML
MHTML(MIME HTML,Multipurpose Internet Mail Extensions HyperText Markup Language),就是將Data URI以附件的形式附加到頁面頁面上,具體示例以下:
/** FilePath: http://example.com/test.css */ /*!@ignore Content-Type: multipart/related; boundary="_ANY_SEPARATOR" --_ANY_SEPARATOR Content-Location:myidBackground Content-Transfer-Encoding:base64 iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg== --_ANY_SEPARATOR-- */ .myid { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="); *background-image: url(mhtml:http://example.com/test.css!myidBackground); }
上面註釋的部分就是定義一個名爲myidBackground的Base64編碼圖片,而後在class爲myid的css中使用。
注意:一、boundary字段值可自定義;
二、附件的末行必須爲boundary字段值;
三、附件內容不能被壓縮工具擦寫掉;
四、因爲高版本的IE在使用IE8兼容模式時能認識*這個css hack,但卻不支持mhtml,因此會致使背景圖片失效。應該採用IE的條件註釋更爲穩妥。
10、安全問題
當在IE6/7的HTTPS頁面中使用Data URI時會提醒
MS 的解釋是:
您正在查看的網站是個安全網站。它使用了 SSL (安全套接字層)或 PCT(保密通信技術)這樣的安全協議來確保您所收發信息的安全性。
當站點使用安全協議時,您提供的信息例如姓名或信用卡號碼等都通過加密,其餘人沒法讀取。然而,這個網頁同時包含未使用該安全協議的項目。
也就是說問題在scheme字段上,因爲全站都採用https的scheme,而data scheme則被視爲不安全的協議了。
11、應用
1. 繞過瀏覽器過濾
// 繞過瀏覽器過濾 http://example.com/text.php?t="><script src="data:text/html,<script>alert("Xss")</script><
2. 批量請求圖片
$.get('http://imgs.foo.com', {ids:[1,2,3,4,5,6,7]}, function(data){ var imgs = [] data.each(function(i, dataUri){ imgs.push($(['<img src="data:image/jpeg;base64,', dataUri, '"/>'].join(''))) }) $(body).append(imgs) })
12、徹底理解Base64編碼
Base64字符集: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
對以某編碼方式編碼後的字節數組爲對象,以3個字節爲一組,按順序排列24bit數據,而後以6bit一組分紅4組;再在每組的最高位補2個0湊足一個字節。這時一組就有4個字節了。若字節數組不是3的倍數,那麼最後一組就填充1到2個0字節。而後按Base64編碼方式(就是映射關係)對字節數組進行解碼,就會獲得平時看到的Base64編碼文本。對於字節數組不是3的倍數,最後一組填充1到2個0字節的狀況,填補的0字節對應的是=(等號)。
①. 對AB進行ASCII編碼:獲得A(65)B(66) ②. 轉成二進制形式:獲得A(01000001)B(01000010) ③. 以3個字節爲一組,非3的倍數補0字節:010000010100001000000000 ④. 以6bit爲一組後高位補兩個0:(00 010000)(00 010100)(00 001000)(00 000000) ⑤. 轉爲十進制:(16)(20)(8)(0) ⑥. 根據映射關係解碼:QUI=
十3、總結
Data URI Scheme就介紹到這裏吧,各位一塊兒來分享實戰經驗吧!
尊重原創,轉載請註明來自:http://www.cnblogs.com/fsjohnhuang/p/3903688.html ^_^肥仔John