我有一个棘手的问题,我现在已经有一段时间了。
我正在寻找一种解决方案,我可以在没有本地存储的情况下将文件保存到用户计算机,因为本地存储有5MB的限制。我希望"保存到文件" -dialog,但我想保存的数据只能在javascript中使用,我想阻止将数据发送回服务器然后再发送。
用例是,正在处理的服务是保存用户数据的压缩和加密块,因此服务器不知道这些块中的数据是什么,并且通过将数据发送回服务器,这将导致4时间流量和服务器正在接收未加密的数据,这将使整个加密无效。
我发现了一个javascript函数,可以使用"保存到文件" -dialog将数据保存到用户计算机,但是这项工作已经停止,并且不完全支持。这是:http://www.w3.org/TR/file-writer-api/
因为我没有window.saveAs,从Blob对象保存数据而不将所有内容发送到服务器的方法是什么?
如果我能得到一个提示,搜索的内容会很棒。
我知道这很有效,因为MEGA正在这样做,但我想要自己的解决方案:)
答案 0 :(得分:15)
您最好的选择是使用blob网址(这是一个指向浏览器内存中对象的特殊网址):
var myBlob = ...;
var blobUrl = URL.createObjectURL(myBlob);
现在您可以选择简单地重定向到此网址(window.location.replace(blobUrl)
),或创建指向它的链接。第二种解决方案允许您指定默认文件名:
var link = document.createElement("a"); // Or maybe get it from the current document
link.href = blobUrl;
link.download = "aDefaultFileName.txt";
link.innerHTML = "Click here to download the file";
document.body.appendChild(link); // Or append it whereever you want
答案 1 :(得分:0)
FileSaver.js为某些没有它的浏览器实现saveAs
https://github.com/eligrey/FileSaver.js
使用FileSaver.js 1.3.8在Chromium 75和Firefox 68上进行了测试,两者均未使用saveAs
。
工作原理似乎只是create an <a
element and click it with JavaScript,这是网络的恐怖。
这是一个演示,它将使用canvas.toBlob
生成的blob保存到具有所选名称mypng.png
的下载文件夹中:
var canvas = document.getElementById("my-canvas");
var ctx = canvas.getContext("2d");
var pixel_size = 1;
function draw() {
console.log("draw");
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);
}
}
canvas.toBlob(function(blob) {
saveAs(blob, 'mypng.png');
});
}
window.requestAnimationFrame(draw);
<canvas id="my-canvas" width="512" height="512" style="border:1px solid black;"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.min.js"></script>
这是一个动画版本,可以下载多个图像:Convert HTML5 Canvas Sequence to a Video File
另请参阅:
答案 2 :(得分:0)
此节点依赖性更多为utils fs-web;
npm i fs-web
用法
import * as fs from 'fs-web';
async processFetch(url, file_path = 'cache-web') {
const fileName = `${file_path}/${url.split('/').reverse()[0]}`;
let cache_blob: Blob;
await fs.readString(fileName).then((blob) => {
cache_blob = blob;
}).catch(() => { });
if (!!cache_blob) {
this.prepareBlob(cache_blob);
console.log('FROM CACHE');
} else {
await fetch(url, {
headers: {},
}).then((response: any) => {
return response.blob();
}).then((blob: Blob) => {
fs.writeFile(fileName, blob).then(() => {
return fs.readString(fileName);
});
this.prepareBlob(blob);
});
}
}
答案 3 :(得分:0)
这里是直接的方式。
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
document.querySelector('a').click() //can add an id to be specific if multiple anchor tag, and use #id
}, 'image/jpeg', 1); // JPEG at 100% quality
花了一段时间想出这个解决方案,如果这有帮助,请发表评论。 感谢 Sebastien C 的回答。
答案 4 :(得分:-1)
从文件选择器或输入类型=文件文件选择器,将文件名保存到本地存储:
HTML:
<audio id="player1">Your browser does not support the audio element</audio>
JavaScript的:
function picksinglefile() {
var fop = new Windows.Storage.Pickers.FileOpenPicker();
fop.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.musicLibrary;
fop.fileTypeFilter.replaceAll([".mp3", ".wav"]);
fop.pickSingleFileAsync().then(function (file) {
if (file) {
// save the file name to local storage
localStorage.setItem("alarmname$", file.name.toString());
} else {
alert("Operation Cancelled");
}
});
}
然后在您的代码中,当您想要播放所选文件时,请使用以下内容,该文件仅使用音乐库中的名称来获取文件。 (在UWP包清单中,将'Capabilites'设置为包含'Music Library'。)
var l = Windows.Storage.KnownFolders.musicLibrary;
var f = localStorage.getItem("alarmname$").toString(); // retrieve file by name
l.getFileAsync(f).then(function (file) {
// storagefile file is available, create URL from it
var s = window.URL.createObjectURL(file);
var x = document.getElementById("player1");
x.setAttribute("src", s);
x.play();
});