一.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,一樣是正確的.
更多:

