JS魔法堂:Data URI Scheme介紹


一、前言                                

  上周五公司內部的Any Topic Conf.上我和同事們分享了這個主題,有同事說這個有用,有同事說這個沒啥用,后來還延伸到網站性能的話題上,大家討論的激烈程度讓我覺得這次選題還不錯。本篇先不管到底有用與否,僅僅記錄理論知識。也希望大家一起來分享實戰經驗啊!

 

二、從HTTP URI Scheme入手                        

  對於 <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屬性。

  DATA URI Scheme的作用,一般就是將經過Base64編碼的數據嵌入網頁中,從而減少請求資源的鏈接數。上面的DATA URI Scheme中 base64, 后的字符就是經過base64編碼后的數據,瀏覽器會對其解碼並渲染該圖片資源。

 

三、Data URI Scheme格式                                  

  data:[<mime type>][;charset=<charset>][;<encoding>],<encoded data>

  ①.  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>] 方式編碼后的數據,則會報異常

 

四、示例                          

/**
 * 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>

 

五、優點&缺點                        

 優點:

  ①. 減少資源請求鏈接數。

 缺點:

  ①. 不會被瀏覽器緩存起來;
  ②. 移動端性能比http URI scheme低。
 

六、優化方案                          

 通過在css文件的background-image樣式規則使用Data URI Scheme,使其隨css文件一同被瀏覽器緩存起來。

 

七、瀏覽器支持                          

  ①. 支持
  Opera 7.2+ data URI 必須小於4100字符
  IE8+ data URI必須小於32k(IE8不支持js的data URI)
  Chrome、FF和Safari無限制
  ②. 不支持
  IE567
 

八、標簽支持                            

  嵌入圖片的object、img、input[type=image]、script、link和css規則中的background和backgroundImage屬性

 

九、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中使用。

   注意:1、boundary字段值可自定義;

           2、附件的末行必須為boundary字段值;

           3、附件內容不能被壓縮工具擦寫掉;

           4、由於高版本的IE在使用IE8兼容模式時能認識*這個css hack,但卻不支持mhtml,所以會導致背景圖片失效。應該采用IE的條件注釋更為穩妥。

 

十、安全問題                           

   當在IE6/7的HTTPS頁面中使用Data URI時會提醒

                  細說 Data URI

   MS 的解釋是:

您正在查看的網站是個安全網站。它使用了 SSL (安全套接字層)或 PCT(保密通訊技術)這樣的安全協議來確保您所收發信息的安全性。
當站點使用安全協議時,您提供的信息例如姓名或信用卡號碼等都經過加密,其他人無法讀取。然而,這個網頁同時包含未使用該安全協議的項目

   也就是說問題在scheme字段上,由於全站都采用https的scheme,而data scheme則被視為不安全的協議了。

 

十一、應用                           

    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)
})

 

十二、完全理解Base64編碼                      

  Base64字符集: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 

  字節與字符映射關系(十進制):從0開始到63
  原理:
  對以某編碼方式編碼后的字節數組為對象,以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=

 

十三、總結                          

  Data URI Scheme就介紹到這里吧,各位一起來分享實戰經驗吧!

  尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/3903688.html  ^_^肥仔John

 
十四、THANKS                          
http://www.cnblogs.com/hustskyking/p/data-uri.html(待整理)
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM