什么时候调用URL.revokeObjectURL是安全的?

问题描述 投票:18回答:1

如果我理解正确,URL.createObjectURL会创建一个表示文件或blob的URL。因为URL只是一个字符串,所以浏览器无法知道何时完成了URL所代表的资源,因此提供了URL.revokeObjectURL函数。

MDN显示this example

var canvas = document.getElementById("canvas");

canvas.toBlob(function(blob) {
  var newImg = document.createElement("img");
  var url = URL.createObjectURL(blob);

  newImg.onload = function() {
    // no longer need to read the blob so it's revoked
    URL.revokeObjectURL(url);
  };

  newImg.src = url;
  document.body.appendChild(newImg);
});

所以有些问题

  1. 在分配newImg.src后,更改代码以立即撤销URL是否安全? var canvas = document.getElementById("canvas"); canvas.toBlob(function(blob) { var newImg = document.createElement("img"); var url = URL.createObjectURL(blob); newImg.src = url; // no longer need to read the blob as it's assigned to newImg.src URL.revokeObjectURL(url); document.body.appendChild(newImg); }); 我猜测答案是“不”,因为可能没有任何事情在newImg.src = url;上开始。它仍然只是一个字符串,并将保持这样,直到当前的JavaScript事件退出。或者是吗?
  2. 撤销URL是否有效/合法/正确但是知道它被其他对象引用仍然使用它吗? var canvas = document.getElementById("canvas"); canvas.toBlob(function(blob) { var newImg = document.createElement("img"); var url = URL.createObjectURL(blob); newImg.onload = function() { // no longer need to read the blob so it's revoked URL.revokeObjectURL(url); // Use the URL again even though it's revoked var newImg2 = new Image(): newImg2.src = url; }; newImg.src = url; document.body.appendChild(newImg); }); 在这种情况下,我正在分配newImg2.src = url,即使我已经撤销了URL。想法是newImg仍然引用blob URL,所以它似乎有效 someImage.src = someOtherImage.src 随时。是吗?
javascript html5
1个回答
5
投票

好吧,按照@ adeneo的建议我测试了这个

$('#test').on('change', function(e) {
	var newImg = document.createElement("img");
    var url = URL.createObjectURL( e.target.files[0] )
    console.log(url);
    
    newImg.src = url;
    URL.revokeObjectURL(url);
    document.body.appendChild(newImg);
    console.log(url);
});

$('#test3').on('change', function(e) {
	var newImg = document.createElement("img");
    var url = URL.createObjectURL( e.target.files[0] )
    console.log(url);
    
    newImg.src = url;
    newImg.onload = function() {
    	URL.revokeObjectURL(url);
    	document.body.appendChild(newImg);
      var i = new Image();
      i.src=  newImg.src;
      document.body.appendChild(i);
      setTimeout(function() {
        var g = new Image();
        g.src = newImg.src;
        document.body.appendChild(g);
      }, 3000);
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>test revoke before use</p>
<input type="file" id="test"/>
<br />
<br />
<br />
<p>test use revoke use</p>
<input type="file" id="test3" />

至少在Firefox中,一旦调用了URL.revokeObjectURL,即使其他东西正在访问它,也无法再使用URL。

所以问题中的#1和#2都失败了,即使在#2中newImg.src仍然有URL,一旦URL.revokeObjectURL被调用,URL将无法在其他任何地方工作。

© www.soinside.com 2019 - 2024. All rights reserved.