检查所选文件是否仍然存在(javascript)

问题描述 投票:0回答:3

我的页面上有 2 个元素 输入类型=“文件”和按钮 单击按钮时,我想检查输入元素上选择的文件是否仍然存在。假设文件在选择之后和单击按钮之前被删除或重命名。

有办法做到这一点吗?即使只是一个简单的警报代码,无论它是否存在都会有帮助..谢谢

javascript file input
3个回答
3
投票

您可以使用

URL.createObjectURL
方法,该方法将创建指向磁盘上文件的直接指针。

然后要检查它是否已被删除/重命名,您可以简单地尝试获取它(通过

fetch
API,或通过XHR)。

let url;
inp.onchange = e => {
  url = URL.createObjectURL(inp.files[0]);
  btn.disabled = false;
}
btn.onclick = e => {
  fetch(url)
    .then((r) => console.log("File still exists"))
    .catch(e => console.log("File has been removed or renamed"));
}
<input type="file" id="inp">
<button disabled id="btn">check if deleted</button>

ES5 版本: (有很多怪癖需要处理...仅在 FF Safari 和 chrome 中测试)

var url;
inp.onchange = function(e) {
  url = URL.createObjectURL(inp.files[0]);
  btn.disabled = false;
}
btn.onclick = function(e) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', url); // cache trick for Safari
  xhr.responseType = 'blob';
  var headers = { // Safari uses the cache...
    "Pragma": "no-cache",
    "Cache-Control": "no-store, no-cache, must-revalidate, post-check=0, pre-check=0",
    "Expires": 0,
    "Last-Modified": new Date(0), // January 1, 1970
    "If-Modified-Since": new Date(0)
  };
  for (var k in headers) {
    xhr.setRequestHeader(k, headers[k]);
  }
  xhr.onload = function(e) {
    if (xhr.response.size) {
      console.log("File still exists\n");
    } else { // chrome fires the load event
      console.log("File has been removed or renamed (load event)\n");
    }
  };
  xhr.onerror = function(e) { // sometimes it fires an error
    console.log("File has been removed or renamed (error event)\n");
  };
  try {
    xhr.send();
  } catch (e) { // sometimes it throws in FF
    console.log("File has been removed or renamed (caught)\n");
  }
}
<input type="file" id="inp">
<button disabled id="btn">check if deleted</button>

还有 Safari 的小提琴,它不会从 stacksnippet® 的 null 起源的 iframe 中获取 BlobURI :
ES6ES5


0
投票

扩展 @Kaiido 答案:从 URL 加载将加载整个文件。如果文件很大,则需要很长时间和/或会导致浏览器消耗大量 RAM。在 chrome 上使用 8GB 文件进行测试 - 使用 fetch 时浏览器使用大约 8GB 内存。使用 XHR 时,它似乎不会消耗内存,但请求需要很长时间才能完成。一种可能的解决方法 - 检查 XHR 的进度事件:

xhr.onprogress = function (e) {
  if (e.loaded > 0) {
    xhr.abort();
    console.log("File still exists");
  }
}

0
投票

实际上,您可以在不进行 fetch 或 XHR 的情况下完成此操作,并且无需将整个文件读入内存。为此,我们尝试从文件中读取单个字节,如果失败,那么您就知道该文件不再存在。当文件大小为零时,无论文件是否仍然存在,读取都会成功,但在这种情况下我们可以只使用 fetch。

async function fileExists(file) {
  try {
    if(file.size == 0) {
      await fetch(URL.createObjectURL(file))
    } else {
      await file.slice(0, 1).arrayBuffer()
    }
    console.log("file exists")
    return true
  } catch(e) {
    console.log("file deleted")
    return false
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.