从 Blob 保存到本地文件
从 Blob 保存到本地文件
我有一个难题想向你请教,我已经在努力解决这个问题一段时间了。
我正在寻找一种解决方案,在不使用本地存储的情况下将文件保存到用户的计算机上,因为本地存储有5MB的限制。我想要"保存到文件"对话框,但我要保存的数据只在JavaScript中可用,并且我希望避免将数据发送回服务器,然后再次发送。
使用案例是,我正在开发的服务保存用户数据的压缩和加密块,因此服务器无法知道这些块中包含的内容,通过将数据发送回服务器,会导致4倍的流量,并且服务器将接收到未加密的数据,这将使整个加密变得无效。
我找到了一个JavaScript函数,可以使用"保存到文件"对话框将数据保存到用户的计算机上,但是这个功能已经停止开发,并且不再完全支持。它是这样的:http://www.w3.org/TR/file-writer-api/
所以,由于我没有window.saveAs,有没有其他方法可以在不将所有内容发送到服务器的情况下保存Blob对象中的数据?
如果可以给我一个提示,我可以搜索什么就太好了。
我知道这是可行的,因为MEGA正在使用它,但我想要自己的解决方案 🙂
问题出现的原因:在这段代码中,想要实现将 Blob 对象保存为本地文件的功能。但是在最后一行代码中,使用了 document.querySelector('a').click() 的方式来模拟用户点击下载链接的操作。这种方式虽然可以实现下载文件的功能,但是需要先通过查找选择器来获取对应的 标签,比较麻烦。
解决方法:可以将最后一行代码改为直接调用 link.click() 方法来触发下载操作,不再需要查找选择器。这样就可以直接使用之前创建的 link 对象的引用,无需为该标签添加 ID。
以下是整理后的文章:
在以下代码中,我们尝试实现将 Blob 对象保存为本地文件的功能。具体代码如下:
canvas.toBlob(function(blob){ console.log(typeof(blob)) //let you have 'blob' here var blobUrl = URL.createObjectURL(blob); var link = document.createElement("a"); // Or maybe get it from the current document link.href = blobUrl; link.download = "image.jpg"; link.innerHTML = "Click here to download the file"; document.body.appendChild(link); // Or append it whereever you want link.click(); // Trigger the download }, 'image/jpeg', 1); // JPEG at 100% quality
在这段代码中,我们创建了一个 标签来作为下载链接,并设置了相关属性和内容。最后一行代码 `link.click()` 是为了模拟用户点击下载链接的操作,以触发文件下载。
然而,这种方式需要先通过查找选择器 `document.querySelector('a')` 来获取对应的 标签,比较麻烦。如果页面中有多个 标签,需要使用 ID 或其他方式来准确定位到目标标签。
但是,我们可以通过直接调用 `link.click()` 方法来触发下载操作,而不再需要查找选择器。这样就可以直接使用之前创建的 link 对象的引用,无需为该标签添加 ID。修改后的代码如下:
canvas.toBlob(function(blob){ console.log(typeof(blob)) //let you have 'blob' here var blobUrl = URL.createObjectURL(blob); var link = document.createElement("a"); // Or maybe get it from the current document link.href = blobUrl; link.download = "image.jpg"; link.innerHTML = "Click here to download the file"; document.body.appendChild(link); // Or append it whereever you want link.click(); // Trigger the download }, 'image/jpeg', 1); // JPEG at 100% quality
通过这种方式,我们可以简化代码,直接调用 `link.click()` 方法来触发下载操作,提高代码的可读性和可维护性。
感谢 Sebastien C 的回答,提供了这种简化代码的解决方案。
问题出现的原因:
在一些浏览器中,没有提供直接将Blob保存为本地文件的方法。而在这个例子中,希望将一个由canvas生成的Blob保存为本地文件,但是Chromium 75和Firefox 68浏览器都没有提供相应的方法。
解决方法:
为了解决这个问题,可以使用FileSaver.js库来实现保存Blob到本地文件的功能。FileSaver.js是一个实现了saveAs方法的库,可以在不支持该方法的浏览器上使用。
具体实现步骤如下:
1. 首先,在HTML中引入FileSaver.js库:
2. 在JavaScript中,通过canvas生成一个Blob对象,并使用saveAs方法保存到本地文件:
var canvas = document.getElementById("my-canvas"); var ctx = canvas.getContext("2d"); var pixel_size = 1; function draw() { // 绘制canvas内容 for (x = 0; x < canvas.width; x += pixel_size) { for (y = 0; y < canvas.height; y += pixel_size) { var b = 0.5; ctx.fillStyle = "rgba(" + (x / canvas.width) * 255 + "," + (y / canvas.height) * 255 + "," + b * 255 + ",255)" ; ctx.fillRect(x, y, pixel_size, pixel_size); } } // 生成Blob对象并保存到本地文件 canvas.toBlob(function(blob) { saveAs(blob, 'mypng.png'); }); } // 动画循环 window.requestAnimationFrame(draw);
通过上述方法,就可以将canvas生成的Blob保存为名为"mypng.png"的本地文件。
参考链接:
- [FileSaver.js](https://github.com/eligrey/FileSaver.js)
- [how to save canvas as png image?](https://stackoverflow.com/questions/11112321)
- [JavaScript: Create and save file](https://stackoverflow.com/questions/13405129)
问题:无法将Blob保存到本地文件。
原因:没有正确处理Blob对象,导致无法将其保存为本地文件。
解决方法:使用Blob URL将Blob对象保存为本地文件。
具体步骤如下:
1. 创建Blob URL:使用URL.createObjectURL()方法将Blob对象转换为Blob URL。代码如下:
var myBlob = ...; // 获取到的Blob对象 var blobUrl = URL.createObjectURL(myBlob);
2. 重定向到Blob URL:使用window.location.replace()方法将页面重定向到Blob URL,从而实现文件下载。代码如下:
window.location.replace(blobUrl);
3. 创建下载链接:使用document.createElement()方法创建一个元素,将其href属性设置为Blob URL,将其download属性设置为默认文件名,并将其添加到页面中。代码如下:
var link = document.createElement("a"); // 或者从当前文档中获取元素 link.href = blobUrl; link.download = "aDefaultFileName.txt"; // 默认文件名 link.innerHTML = "Click here to download the file"; document.body.appendChild(link); // 或者将其添加到其他位置
4. 释放内存:通过调用URL.revokeObjectURL()方法释放Blob URL占用的内存。代码如下:
URL.revokeObjectURL(blobUrl);
通过以上步骤,可以将Blob对象保存为本地文件,并正确处理内存释放。