何时可以安全地调用 URL.revokeObjectURL
When is it safe to call URL.revokeObjectURL?
如果我理解正确,URL.createObjectURL
会创建一个表示文件或 blob 的 URL。由于 URL 只是一个字符串,因此浏览器无法知道您何时完成 URL 表示的资源,因此提供了URL.revokeObjectURL
函数。
MDN 显示了这个例子:
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);
});
所以一些问题
在分配 URL 后立即更改代码以撤销 URL 是否安全
newImg.src
?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 事件退出。还是吗?撤销 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); });
在这种情况下,即使我已经撤销了 URL,我也会分配
newImg2.src = 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,该 URL 将无法在其他任何地方工作。
在 React 中,有一个名为 useEffect 的钩子,它所做的一件事是,在你离开组件(函数(之前你想采取什么操作,在那里你释放了之前通过调用 URL.createObjectURL(( 创建的现有对象 URL。
使用 URL.revokeObjectURL 释放现有对象 URL:
useEffect(() => () => URL.revokeObjectURL(file as string), [file])
const onChangeFile = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files[0]) {
setFile(URL.createObjectURL(e.target.files[0]))
}
}
- 如何使用url加载程序在webpack中导入多个图像
- 使用php或javascript从facebook相册URL中删除多余的部分
- Angular JS IE9 Hashbang url rewriting
- JavaScript下拉菜单-点击按钮并根据所选值重定向到url
- 直接下载文件,而不是从window.open(url)
- 动态地改变“”的URL;添加新项目”;链接使用javascript/jquery
- 通过js在新选项卡中有条件地打开url
- CKFinder 3为所选文件返回错误的URL
- 如何获取不属于我项目的上一页的URL
- ReactJS映射:如何仅在url变量不为空时呈现html链接
- 在URL中传递JS对象
- 将纯文本URL转换为可单击链接
- Javascript html每点击一次就会更改url
- 以角度管理动态URL
- Mathias URL shortener
- 如何有效地将游戏数据存储在URL查询字符串中
- 使用带括号的图像URL作为jQuery的背景
- FireFox 无法在 URL.revokeObjectURL 上正常工作
- 何时可以安全地调用 URL.revokeObjectURL
- 我如何才能调用revokeObjectURL只有在URL加载后