参数不是'Blob'类型

33

我已经编写了以下代码,使用文件API显示本地文件中的文本,但是当我单击按钮时,什么也不会发生。在浏览器中检查元素时,我会得到以下错误。我做错了什么?

Uncaught TypeError: Failed to execute 'readAsText' on 'FileReader': parameter 1 is not of type 'Blob'.

<!DOCTYPE html>
    <html>
    <body>

    <p>This example uses the addEventListener() method to attach a click event to a button.</p>

    <button id="myBtn">Try it</button>
    <pre id="file"></pre>

    <script>
    document.getElementById("myBtn").addEventListener("click", function(){
       var file = "test.txt"
       var reader = new FileReader();

       document.getElementById('file').innerText = reader.result;
   
       reader.readAsText(file);

    });
    </script>

    </body>
    </html>


typeof file == "string" // true - Jonathan
4个回答

27

你犯了一些错误。

错误信息提示你正在尝试使用硬编码字符串选择文件。 你无法确定加载哪个文件。File API 只允许你通过文件输入选中的文件进行读取。

第二个错误是在你读取文件之前就试图读取读卡器的result属性。你需要一个事件处理程序来完成这个操作(因为像 Ajax 一样,文件读取是异步的)。

document.getElementById("myBtn").addEventListener("click", function() {

  var reader = new FileReader();
  reader.addEventListener('load', function() {
    document.getElementById('file').innerText = this.result;
  });
  reader.readAsText(document.querySelector('input').files[0]);

});
<input type="file">
<button id="myBtn">Try it</button>
<pre id="file"></pre>


我可以问一下,我们是否可以在选择文件后立即加载文本,而无需点击“试一试”? - Ae Leung
@AeLeung - 如果您有新的问题,请提出新的问题。如果这个答案有用的上下文,请提供一个链接。 - Quentin

15

要将文件内容保存在 innerHtml 中,您必须先读取该文件。仅当文件完全读取时,loadend 事件才会触发,并且您可以无误地访问其内容:

var reader = new FileReader();
var fileToRead = document.querySelector('input').files[0];

// attach event, that will be fired, when read is end
reader.addEventListener("loadend", function() {
   // reader.result contains the contents of blob as a typed array
   // we insert content of file in DOM here
   document.getElementById('file').innerText = reader.result;
});

// start reading a loaded file
reader.readAsText(fileToRead);

您可以在此处阅读更多信息 - 和此处


1
如果想将其读入变量中,该怎么办?我们是否必须显式地将其转储到innerText中? - CromeX
不要忘记 .files[0]; - Adam Fowler
1
loadend 用于加载成功或失败的情况。您可以仅使用“load”事件来进行成功的读取操作。 - daniel

1
正如其他人所说,我注意到缺少 onload 事件。
因此,我有几种不同的方法来展示如何让读者做某些事情,一种是使用 readAsText 进行读取,另一种是使用 readAsDataURL 获取数据作为 base64 字节字符串,我认为后者更好,因为你不必担心 Unicode 和其他奇怪的问号字符。要查看它们的实际效果,只需在监听器中将调用从 uploadFile(); 切换到 uploadFile1();。我还展示了几种不同的方法可以获取文件对象:

document.getElementById("myBtn").addEventListener("click", function() {
  uploadFile1();
}); 

function uploadFile1(){
  var f = myInput.files[0];
  var reader = new FileReader();
  reader.onload = processFile(f);
  reader.readAsText(f); 
}

function uploadFile(){
  var f = document.querySelector('input').files[0];
  var reader = new FileReader();
  reader.onload = processFile(f);
  reader.readAsDataURL(f); 
}

function processFile(theFile){
  return function(e) { 
    // Use the .split I've included when calling this from uploadFile()
    var theBytes = e.target.result; //.split('base64,')[1]; 
    document.getElementById('file').innerText = theBytes;
  }
}
<input id="myInput" type="file">    
<button id="myBtn">Try it</button>
<span id="file"></span>

通常情况下,我认为您应该只需执行以下操作:

<input type="button" onclick="uploadFile()" id="myBtn">Try it</button>

不需要添加那个监听器,但由于某些原因在JSFiddle上无法工作。

https://jsfiddle.net/navyjax2/heLmxegn/1/


-1

嗯!不确定其他情况,但在我的情况下,通过使用fileObjects [0] .file解决了问题。

一个好的方法是在控制台中打印您的“文件”或“文件对象”,然后查看最终是否需要.file。


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