如果我理解正确,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);
});
所以有些问题
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事件退出。或者是吗?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
随时。是吗?好吧,按照@ 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将无法在其他任何地方工作。