Javascript FileReader对象在读取同一文件的Chrome和FireFox中返回不同的值
在所选文件内容被修改后,下面的代码(angular 2)在Chrome和Firefox中返回不同的结果:Javascript FileReader对象在读取同一文件的Chrome和FireFox中返回不同的值,javascript,google-chrome,firefox,Javascript,Google Chrome,Firefox,在所选文件内容被修改后,下面的代码(angular 2)在Chrome和Firefox中返回不同的结果: isExistedFiles(funcCallBack: any) { try { const r = new FileReader(); r.onerror = function (e: any) { funcCallBack(0); }; r.onload = function (e: any) {
isExistedFiles(funcCallBack: any) {
try {
const r = new FileReader();
r.onerror = function (e: any) {
funcCallBack(0);
};
r.onload = function (e: any) {
funcCallBack(1);
};
r.readAsText(this.files);
} catch (e) {
funcCallBack(0);
}
}
结果:
-Firefox:FileReader{readyState:2,结果:null,错误:DomeException,…
-Chrome:FileReader{readyState:2,结果:“PK…”,错误:null,
为什么会发生这种情况?以及如何修复它?对于用户选择后在磁盘上修改的文件,它们确实有不同的行为,甚至在不同的操作系统上,这种行为也会发生变化。
(此答案仅基于对macOS系统的观察,可能与您的不匹配) Chrome会在访问时更新文件的元数据。
Firefox不会在access中更新这些元数据,因此,如果您尝试读取时的文件大小小于用户选择时的大小,则FileReader将抛出错误。
这是因为,由于它使用旧的元数据,它被要求读取不存在的数据 为了使其更直观,让我们在用户选择时获取文件的内容:
abcdefghijklmnopqrstuvwxyz
当Firefox请求文件的元数据时,操作系统会告诉它size:26
现在,让我们将此文件的内容更改为
abc
如果我们尝试通过文件读取器读取此文件,FF将使用操作系统提供给它的元数据(大小:26)。因此,它将尝试读取此文件的第26个字节。显然,这不起作用…这就是你的原因
那么现在,“如何修复它” 好吧,这取决于你的意思……如果你想在Firefox上使用Chrome的行为,你可以使用blobURI adn AJAX在磁盘上获取文件,实际将文件从磁盘加载到内存,并因此使用新的元数据 但请注意,这在Safari中不起作用,Safari本身会从选定的文件创建blobURI,但如果它已被更改,则不允许我们在磁盘上获取新的blobURI 另一个更难看的解决方法是在用户选择文件时只给您“原样”的文件,即在内存中创建一个副本(我认为FileReader.readAsArrayBuffer是最跨浏览器的方法)。但是如果您的用户修改了它,他们可能会失望地看到他们的更改没有反映出来 因此,最好的解决方案可能是简单地处理错误,并向用户提供一条消息,向他们解释修改已选择的文件是不好的,然后让他们再次选择它
Ps:chrome错误说明了什么?Firefox中的DomeException抱怨了什么?它报告了一条消息:“文件无法读取”。