IE 释放 blob url
Posted
技术标签:
【中文标题】IE 释放 blob url【英文标题】:IE frees blob urls 【发布时间】:2013-12-18 09:43:38 【问题描述】:我有两个音频文件必须一个接一个地播放。 为此,我使用 XHR 下载了这两个文件
var xhr = new XMLHttpRequest();
xhr.open('GET', fileURL, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function ()
data = new Uint8Array(xhr.response);
//... other handling code
;
并从它们构造一个 Blob
var blob = new Blob([data], type: 'video/mp4')
这些我用来构建 Blob URL
var url = URL.createObjectURL(blob)
然后注入<audio>
标签。 (audioDOM.src = url;
)
此过程适用于 Chrome 和 Firefox。但是 IE11 有时会给我一个问题,它显示以下通知:
通过关闭它们所针对的 blob 来撤销一个或多个 blob URL 被创造。这些 URL 将不再解析为数据支持 该 URL 已被释放。
然而,最奇怪的部分是它确实适用于第一个文件(在 IE 中),但不适用于第二个文件。它们都对整个过程使用相同的代码,只是使用不同的fileURL
来调用。这两个文件都存在,已正确下载并已记录到控制台进行验证。
我尝试在构建 blob 之前复制数据,但这似乎无关紧要:错误仍然存在。
有没有人知道是什么导致了问题以及如何解决?
在 sbgoran 之后编辑:
整个脚本在单个文档上运行,不会重新加载。我仍然很困惑为什么会这样。当音频无法加载时,我确实设法通过循环和创建新 URL 来创建解决方法,但这不是一个可行的解决方案。奇怪的是,上述方法随机失败:有时 URL 在加载到 <audio>
标记时可用,有时则不可用。
【问题讨论】:
您是否有理由不能将 src=whatever 和 onended=playsecond() 用于第一次或如下所示:***.com/questions/9326288 ?... 使用这样的 blob 似乎效率低下且不必要。跨度> 是的,我有充分的理由这样做。其中之一是在我的最终实现中,对原始两个文件中的数据进行了编辑以形成两个新文件。然而,这对失败率没有影响:我进行了测试,其中按照上述方式简单地复制了 blob,但问题仍然存在。 (所以操作对这里所说的问题没有影响) 【参考方案1】:除了 sbgoran 的回答之外,我还有另一个可能的原因 - 作为discussed on WhatWG mailing list,IE 中存在一个错误,当指向它的变量超出范围时,它会导致 Blob 被垃圾收集 - 即使仍然存在对象指向尚未撤销的 Blob 的 URL。
解决方法可以依赖于在需要对象 URL 时保留变量中的原始 Blob 对象,然后使变量无效并随后撤销其对象 URL。
【讨论】:
+1:这听起来完全合理。我本来可以让Blob
在某个地方活着,只是出于良好的设计;该 URL “感觉”不像是对我的强烈引用。
听起来确实有道理。但是,经过测试,这似乎并不能解决问题。我将对 blob 和 uri 的引用都存储在一个数组中,但问题仍然存在。
我的错。这确实解决了问题。释放内存的时候记得先撤销object url,不然还是会出现提示。【参考方案2】:
基于MSDN createObjectURL method 页面的Remarks
部分,IE 可能会抱怨很多事情。我不确定您之前是否阅读过此 MSDN 页面,但也许它可以在某些方面有所帮助。
我会特别检查有关 blob url 来源政策的说明
Blob url 受制于原始策略。这意味着它们只能用于与运行创建 url 的脚本的文档具有相同来源的文档中。如果您需要使用在不同域中运行的 blob 对象,则必须使用 postMessage API 将 blob 数据发送到框架,然后在那里创建 blob: url。
和
createObjectURL 返回的 URL 在创建文档的生命周期内有效,
【讨论】:
是的,我已经知道了。如果加载音频失败,我确实设法通过重新创建 blob url 来解决问题,但我还没有找到可靠的解决方案。即使通知声称 blob 数据不可用,但情况并非如此:即使在发出通知后仍然可以访问 blob 数据。【参考方案3】:然后注入到
<audio>
标签中。
你能给我这个代码吗?
也许 IE 有某种垃圾收集器,只要没有包含 blob url 的 DOMString
实例,它就会释放 blob url。
根据这个理论,使用innerhtml
(可能还有 setAttribute ?)创建您的音频标签,我的意思是连接 url (foo.innerHTML = '<audio src="' + url + '" />';
) 意味着唯一包含 blob url 的 DOMString
(由URL.createObjectURL
) 将在函数结束后的某个时间被垃圾收集。
【讨论】:
注入只是通过使用audioDOM.src = url;
发生的,所以应该不是问题以上是关于IE 释放 blob url的主要内容,如果未能解决你的问题,请参考以下文章
关于iframe 关闭后,IE下不能释放内存的问题,跪求解决方案.
VB使用webbrowser控件时怎样释放内存?我使用了许多webbrowser数组时,只见占用内存越来越大。最后崩溃
HttpClient 4.0.1 - 如何释放连接? [复制]