从 Blob 保存到本地文件

10 浏览
0 Comments

从 Blob 保存到本地文件

我有一个难题想向你请教,我已经在努力解决这个问题一段时间了。

我正在寻找一种解决方案,在不使用本地存储的情况下将文件保存到用户的计算机上,因为本地存储有5MB的限制。我想要"保存到文件"对话框,但我要保存的数据只在JavaScript中可用,并且我希望避免将数据发送回服务器,然后再次发送。

使用案例是,我正在开发的服务保存用户数据的压缩和加密块,因此服务器无法知道这些块中包含的内容,通过将数据发送回服务器,会导致4倍的流量,并且服务器将接收到未加密的数据,这将使整个加密变得无效。

我找到了一个JavaScript函数,可以使用"保存到文件"对话框将数据保存到用户的计算机上,但是这个功能已经停止开发,并且不再完全支持。它是这样的:http://www.w3.org/TR/file-writer-api/

所以,由于我没有window.saveAs,有没有其他方法可以在不将所有内容发送到服务器的情况下保存Blob对象中的数据?

如果可以给我一个提示,我可以搜索什么就太好了。

我知道这是可行的,因为MEGA正在使用它,但我想要自己的解决方案 🙂

0
0 Comments

问题出现的原因:在这段代码中,想要实现将 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 的回答,提供了这种简化代码的解决方案。

0
0 Comments

问题出现的原因:

在一些浏览器中,没有提供直接将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)

0
0 Comments

问题:无法将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对象保存为本地文件,并正确处理内存释放。

0