URL.createObjectURL和URL.revokeObjectURL 轉

一.URL.createObjectURL 

URL.createObjectURL()方法會根據傳入的參數創建一個指向該參數對象的URL. 這個URL的生命僅存在於它被創建的這個文檔裏. 新的對象URL指向執行的File對象或者是Blob對象.

 

語法: 

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

 

參考原文: https://developer.mozilla.org/en-US/docs/Web/API/URL.revokeObjectURL 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章