浏览器在被<input type="file" />
选中后是否有办法“锁定”文件?现在我可以选择一个文件,用JavaScript开始一些操作,同时我可以从我的磁盘中删除它,这会导致JavaScript代码出错。
编辑我的目标是确保在使用JavaScript处理文件时无法删除该文件。
答案 0 :(得分:3)
没有办法。仅仅因为JS是客户端语言,即使在服务器端,这也是不可能的,因为您无法与用户计算机进行交互。要做到这一点,你需要你的桌面应用程序,例如将文件复制并锁定它。
如果要实现这一点,则必须在浏览器中实现。
编辑补充:
如果您考虑一下为什么这已经没有在浏览器中实现,也许是因为如果您在上传文件时会发生什么?保持锁定?
答案 1 :(得分:0)
是:您可以在内存中创建副本,并使用此副本代替用户磁盘上的文件。
您必须首先阅读其内容并从那里创建一个新的文件/ Blob:
let theFile = null;
inp.onchange = async function(e) {
theFile = await saveBlob(inp.files[0]);
btn.disabled = false;
inp.disabled = true;
}
btn.onclick = e => {
console.log(theFile);
let reader = new FileReader();
// to prove it's really still there
reader.onload = e => console.log(new Uint8Array(reader.result));
reader.onerror = e => console.log(e);
reader.readAsArrayBuffer(theFile.slice(0, 4));
}
function saveBlob(blob) {
let reader = new FileReader();
return new Promise((res, rej) => {
reader.onload = e => {
if (blob instanceof File) {
// tries to keep it as a File, but beware some implementations still have bugs
res( new File([reader.result], blob.name, {type: blob.type}) );
} else {
res( new Blob([reader.result], {type: blob.type}) );
}
};
reader.onerror = rej; // already removed ???
reader.readAsArrayBuffer(blob);
});
}
<input type="file" id="inp">
<button id="btn" disabled>I did remove it from disk</button>
另一种方法是将其存储在indexedDB中。
然后,您可以使用此副本,并确保它将保留在内存中,无论用户使用原始文件做什么。
如果您需要保留的时间超过文档的生命周期,则可以创建一个blobURI(URL.createObjectURL(theFile)
),您可以将其存储在localStorage中,并使用fetch(blobURI).then(r=>r.blob());
进行重新加载或重定向检索。
如果你需要它存活更长时间(硬刷新会杀死blobURI的引用),那么使用indexedDB。
修改以回复question's edit。
显然,你无法在用户磁盘上更改文件的权限,但是你不需要这样做,因为你可以获得它的副本。