1. 程式人生 > 實用技巧 >JavaScript ObjectURL | URL.createObjectURL和URL.revokeObjectURL

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

更多:

JavaScript Blob二進位制檔案物件(二)使用示例

JavaScript Blob二進位制檔案物件(一)

JavaScript ArrayBuffer 二進位制陣列(二) 應用場景