JavaScript ObjectURL | URL.createObjectURL和URL.revokeObjectURL
一.URL.createObjectURL
URL.createObjectURL()方法會根據傳入的引數建立一個指向該引數物件的URL. 這個URL的生命僅存在於它被建立的這個文件裡. 新的物件URL指向執行的File物件或者是Blob物件,或者MediaSource
物件。
語法:
objectURL = URL.createObjectURL(blob || file);
引數:
File物件或者Blob物件
這裡大概說下File物件和Blob物件:
File物件,就是一個檔案,比如我用input type="file"標籤來上傳檔案,那麼裡面的每個檔案都是一個File物件.
Blob物件,就是二進位制資料,比如通過new Blob()建立的物件就是Blob物件.又比如,在XMLHttpRequest裡,如果指定responseType為blob,那麼得到的返回值也是一個blob物件.
注意點:
每次呼叫createObjectURL的時候,一個新的URL物件就被建立了.即使你已經為同一個檔案建立過一個URL. 如果你不再需要這個物件,要釋放它,需要使用URL.revokeObjectURL()方法. 當頁面被關閉,瀏覽器會自動釋放它,但是為了最佳效能和記憶體使用,當確保不再用得到它的時候,就應該釋放它.
二.URL.revokeObjectURL
URL.revokeObjectURL()方法會釋放一個通過URL.createObjectURL()建立的物件URL. 當你要已經用過了這個物件URL,然後要讓瀏覽器知道這個URL已經不再需要指向對應的檔案的時候,就需要呼叫這個方法.
具體的意思就是說,一個物件URL,使用這個url是可以訪問到指定的檔案的,但是我可能只需要訪問一次,一旦已經訪問到了,這個物件URL就不再需要了,就被釋放掉,被釋放掉以後,這個物件URL就不再指向指定的檔案了.
比如一張圖片,我建立了一個物件URL,然後通過這個物件URL,我頁面里加載了這張圖.既然已經被載入,並且不需要再次載入這張圖,那我就把這個物件URL釋放,然後這個URL就不再指向這張圖了.
語法:
window.URL.revokeObjectURL(objectURL);
引數:
objectURL 是一個通過URL.createObjectURL()方法建立的物件URL.
這兩個方法不支援低版本瀏覽器.
最後,給個綜合栗子:
通過ajax獲取一張圖片,顯示在頁面裡.
html:
<body> <button id="getPic">獲取圖片的Blob資料</button> </body>
js:
//獲取圖片Blob資料 document.getElementById('getPic').onclick = function(e){ $.ajax({ type:'GET', url:'img.png', resDataType:'blob', imgType:'png', success:function(resText,resXML){ var img = document.createElement('img'); var objectUrl = window.URL.createObjectURL(resText); img.src = objectUrl; img.onload = function(){ window.URL.revokeObjectURL(objectUrl); }; document.body.appendChild(img); }, fail:function(err){ console.log(err) } }); e.preventDefault(); }
指定返回的資料格式為blob二進位制資料.
通過返回的圖片二進位制資料來建立一個物件URL.
當圖片載入完成後釋放物件URL.
ajax.js:
var $={}; $.ajax = function(options){ //1.獲取引數 var type = options.type.toUpperCase() || 'GET'; var resDataType = options.resDataType || 'string'; var reqDataType = options.reqDataType || 'string'; var url = options.url; var data = options.data; var success = options.success; var fail = options.fail; var progress = options.progress; var imgType = options.imgType || 'jpg'; //2.獲取xhr物件 var xhr = $.getXhr(); //3.建立連線 xhr.open(type,url); /*指定返回資料的格式需要在傳送請求之前*/ if(resDataType==='blob'){ xhr.responseType = 'blob'; } //4.傳送請求 if(type==='GET'){ xhr.send(null) } else if(type==='POST') { if(progress){ xhr.upload.onprogress = progress; } if(reqDataType==='json'){ xhr.setRequestHeader('Content-Type','application/json;charset=UTF-8'); data = JSON.stringify(data); //只能傳送字串格式的json,不能直接傳送json } if(reqDataType==='string'){ xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); } xhr.send(data); } //5.接收資料 xhr.onreadystatechange = function(){ if(this.readyState===4 && (this.status>=200 && this.status<300)){ var res; if(resDataType==='json'){ res = JSON.parse(this.responseText); success.call(this,res,this.responseXML) } if(resDataType==='blob'){ res = new Blob([this.response],{type:'image/'+imgType}); success.call(this,res) } } }; };
指定響應的格式是二進位制資料.
使用xhr.response來獲取響應的二進位制資料,而不是xhr.responseText. 當定義了xhr.responseType='blob'以後,xhr就沒有responseText屬性了.
這裡雖然使用new Blob(),但其實不用它,直接返回xhr.response,一樣是正確的.
更多: