一.URL.createObjectURL URL.createObjectURL()方法會根據(jù)傳入的參數(shù)創(chuàng)建一個指向該參數(shù)對象的URL. 這個URL的生命僅存在于它被創(chuàng)建的這個文檔里. 新的對象URL指向執(zhí)行的File對象或者是Blob對象.
語法: objectURL = URL.createObjectURL(blob || file);
參數(shù): File對象或者Blob對象 這里大概說下File對象和Blob對象: File對象,就是一個文件,比如我用input type="file"標(biāo)簽來上傳文件,那么里面的每個文件都是一個File對象. Blob對象,就是二進(jìn)制數(shù)據(jù),比如通過new Blob()創(chuàng)建的對象就是Blob對象.又比如,在XMLHttpRequest里,如果指定responseType為blob,那么得到的返回值也是一個blob對象.
注意點(diǎn): 每次調(diào)用createObjectURL的時候,一個新的URL對象就被創(chuàng)建了.即使你已經(jīng)為同一個文件創(chuàng)建過一個URL. 如果你不再需要這個對象,要釋放它,需要使用URL.revokeObjectURL()方法. 當(dāng)頁面被關(guān)閉,瀏覽器會自動釋放它,但是為了最佳性能和內(nèi)存使用,當(dāng)確保不再用得到它的時候,就應(yīng)該釋放它.
二.URL.revokeObjectURL URL.revokeObjectURL()方法會釋放一個通過URL.createObjectURL()創(chuàng)建的對象URL. 當(dāng)你要已經(jīng)用過了這個對象URL,然后要讓瀏覽器知道這個URL已經(jīng)不再需要指向?qū)?yīng)的文件的時候,就需要調(diào)用這個方法. 具體的意思就是說,一個對象URL,使用這個url是可以訪問到指定的文件的,但是我可能只需要訪問一次,一旦已經(jīng)訪問到了,這個對象URL就不再需要了,就被釋放掉,被釋放掉以后,這個對象URL就不再指向指定的文件了. 比如一張圖片,我創(chuàng)建了一個對象URL,然后通過這個對象URL,我頁面里加載了這張圖.既然已經(jīng)被加載,并且不需要再次加載這張圖,那我就把這個對象URL釋放,然后這個URL就不再指向這張圖了.
語法: window.URL.revokeObjectURL(objectURL);
參數(shù): objectURL 是一個通過URL.createObjectURL()方法創(chuàng)建的對象URL.
這兩個方法不支持低版本瀏覽器.
最后,給個綜合栗子: 通過ajax獲取一張圖片,顯示在頁面里. html: <body> <button id="getPic">獲取圖片的Blob數(shù)據(jù)</button> </body>
js: //獲取圖片Blob數(shù)據(jù) 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(); } 指定返回的數(shù)據(jù)格式為blob二進(jìn)制數(shù)據(jù). 通過返回的圖片二進(jìn)制數(shù)據(jù)來創(chuàng)建一個對象URL. 當(dāng)圖片加載完成后釋放對象URL.
ajax.js: var $={}; $.ajax = function(options){ //1.獲取參數(shù) 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); /*指定返回數(shù)據(jù)的格式需要在發(fā)送請求之前*/ if(resDataType===‘blob‘){ xhr.responseType = ‘blob‘; } //4.發(fā)送請求 if(type===‘GET‘){ xhr.send(null) } else if(type===‘POST‘) { if(progress){ xhr.upload.onprogress = progress; } if(reqDataType===‘json‘){ xhr.setRequestHeader(‘Content-Type‘,‘a(chǎn)pplication/json;charset=UTF-8‘); data = JSON.stringify(data); //只能發(fā)送字符串格式的json,不能直接發(fā)送json } if(reqDataType===‘string‘){ xhr.setRequestHeader(‘Content-Type‘,‘a(chǎn)pplication/x-www-form-urlencoded‘); } xhr.send(data); } //5.接收數(shù)據(jù) 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) } } }; }; 指定響應(yīng)的格式是二進(jìn)制數(shù)據(jù). 使用xhr.response來獲取響應(yīng)的二進(jìn)制數(shù)據(jù),而不是xhr.responseText. 當(dāng)定義了xhr.responseType=‘blob‘以后,xhr就沒有responseText屬性了. 這里雖然使用new Blob(),但其實(shí)不用它,直接返回xhr.response,一樣是正確的.
參考原文: https://developer.mozilla.org/en-US/docs/Web/API/URL.revokeObjectURL
|
|