检查本地文件是否已更改

4

我有一个Web应用程序,在html5的FileReader API下,用户可以选择本地文件作为输入。是否有任何方法可以检查文件是否已更改,可在现代浏览器中工作?

历史上,在某些浏览器中,可以通过轮询文件对象并比较File.lastModifiedDate(不建议使用)或File.lastModified属性来实现此操作,如在此QA中所述:Check if file has changed using HTML5 File API。然而,规范说明,lastModifiedDate和其他文件数据应该是用户首次选择文件时的快照,因此这种方法不起作用(最近的大多数浏览器版本似乎都遵循规范,因此无法使用此技巧)。

我希望能够通过读取文件来检查更改。这种方法有点奏效,但是一旦磁盘上的文件发生更改,Chrome和Firefox会抛出错误,指出DOMException:请求的文件无法读取,通常是由于在获取文件引用后发生了权限问题。有没有什么办法绕过这个问题?

这是我尝试过的:

let oldText

setInterval(function () {
  const fileObj = document.getElementById('myFileInput').files[0]
  const reader = new FileReader()
  reader.onload = evt => {
      const text = evt.target.result
      if (text !== oldText) {
        console.log("The file has changed!")
        oldText = text
      }
    }
    reader.readAsText(fileObj)
}, 1000)

...或更简单地说:

const fileObj = document.getElementById('myFileInput').files[0]
const reader = new FileReader()
reader.readAsText(fileObj)  // works
// now lets edit the file and try again
reader.readAsText(fileObj)  // fails

reader.readAsText() 的工作方式是符合预期的,直到文件被更改,此时它将抛出上述错误。我想这是某种安全措施,尽管我不完全理解它试图保护用户免受什么。我可以做些什么呢?


4
这是一项安全措施。你无法做任何事情。 - Guy Incognito
规范的一部分涵盖了在选择后文件更改时禁止读取的内容,在此处 - T.J. Crowder
1个回答

2
如果/当本地文件系统API在浏览器中实现时,这将再次成为可能。它将在2020年10月发布的Google Chrome 85中部分启用
与FileReader API不同,它需要明确的用户交互,因此您可以这样做:
myFileInput.addEventListener('change', async (e) => {
  const fh = await window.chooseFileSystemEntries()
  // fh is now a FileSystemFileHandle object
  // Use fh.getFile() to get a File object
})

2
Chrome,是的,这也可能意味着Edge(> v44),但目前对于Firefox来说情况不太乐观(https://github.com/mozilla/standards-positions/issues/154),而且考虑到这一点(https://www.zdnet.com/article/apple-declined-to-implement-16-web-apis-in-safari-due-to-privacy-concerns/),Safari似乎也不太可能。 :-| - T.J. Crowder
现在应该接受这个答案了。所有主要的浏览器都支持这个解决方案。 - basquith16

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接