文件字段

文件字段最初是用于通过表单来上传从浏览器机器中获取的文件。在现代浏览器中,也可以从 JavaScript 程序中读取文件。该字段则作为一个看门人角色。脚本不能简单地直接从用户的电脑中读取文件,但是如果用户在这个字段中选择了一个文件,浏览器会将这个行为解释为脚本,便可以访问该文件。

一个文本字段是一个类似于“选择文件”或“浏览”标签的按钮,后面跟着所选文件的信息。

  1. <input type="file">
  2. <script>
  3. let input = document.querySelector("input");
  4. input.addEventListener("change", () => {
  5. if (input.files.length > 0) {
  6. let file = input.files[0];
  7. console.log("You chose", file.name);
  8. if (file.type) console.log("It has type", file.type);
  9. }
  10. });
  11. </script>

文本字段的files属性是一个类数组对象(当然,不是一个真正的数组),包含在字段中所选择的文件。开始时是空的。因此文本字段属性不仅仅是file属性。有时文本字段可以上传多个文件,这使得同时选择多个文件变为可能。

files对象中的对象有name(文件名)、size(文件大小,单位为字节),和type(文件的媒体类型,如text/plainimage/jpeg)等属性。

files属性中不包含文件内容的属性。获取这个内容会比较复杂。由于从硬盘中读取文件会需要一些时间,接口必须是异步的,来避免文档的无响应问题。

  1. <input type="file" multiple>
  2. <script>
  3. let input = document.querySelector("input");
  4. input.addEventListener("change", () => {
  5. for (let file of Array.from(input.files)) {
  6. let reader = new FileReader();
  7. reader.addEventListener("load", () => {
  8. console.log("File", file.name, "starts with",
  9. reader.result.slice(0, 20));
  10. });
  11. reader.readAsText(file);
  12. }
  13. });
  14. </script>

读取文件是通过FileReader对象实现的,注册一个load事件处理器,然后调用readAsText方法,传入我们希望读取的文件,一旦载入完成,readerresult属性内容就是文件内容。

FileReader对象还会在读取文件失败时触发error事件。错误对象本身会存在readererror属性中。这个接口是在Promise成为语言的一部分之前设计的。 你可以把它包装在Promise中,像这样:

  1. function readFileText(file) {
  2. return new Promise((resolve, reject) => {
  3. let reader = new FileReader();
  4. reader.addEventListener(
  5. "load", () => resolve(reader.result));
  6. reader.addEventListener(
  7. "error", () => reject(reader.error));
  8. });
  9. reader.readAsText(file);
  10. });
  11. }