new FileReader().readAsDateURL

524 阅读1分钟

readAsDataURL

readAsDataURL 会将文件内容进行 base64 编码后进行输出

<input type="file" id="file" />
document.getElementById('file').addEventListener(
    'change',
    (fileChoosed) => {
        const reader = new FileReader()
        reader.readAsDataURL(fileChoosed.target.files[0])
        reader.onload = function (readResult) {
            console.log('load complete', readResult.target.result)
        }
    }
)

上述代码执行之后在控制台输出 base64 编码字符串。由于媒体文件的 src 属性,可以通过采用网络地址或者 base64 的方式显示,因此我们可以利用 readAsDataURL 实现对图片的预览。

<input type="file" id="file" />
<img src="" id="imgPreview" />
document.querySelector('#file').addEventListener(
    'change',
    (fileChoosed) => {
        const reader = new FileReader()
        
        reader.readAsDataURL(fileChoosed.target.files[0])
        
        reader.onload = (readResult) => {
            document.querySelector('#imgPreview').src = readResult.target.result
        }
    }
)

注意

  • 一个 FileReader 实例只能同时读取一个文件,例如
  <input type="file" name="file" id="file" multiple>
  <img src="" alt="" srcset="" id="img">
const file = document.getElementById('file')
const img = document.getElementById('img')

file.onchange = (fileChoosed) => {
    const reader = new FileReader()
    
    for (const fileChoosedItem of fileChoosed.target.files) {
        reader.readAsDataURL(fileChoosedItem)
        
        reader.onload = (readResult) => {
            console.log(readResult.target.result)
        }
    }
    
    
}

上述代码只能读取第一个,同步读取第二个会抛出异常

修改删除代码,使之可以正常运行,例如

  • 情况一
file.onchange = (fileChoosed) => {
    
    for (const fileChoosedItem of fileChoosed.target.files) {
        const reader = new FileReader()
        reader.readAsDataURL(fileChoosedItem)
        
        reader.onload = (readResult) => {
            console.log(readResult.target.result)
        }
    }
    
    
}

上述代码每次执行时,在块级作用域内会重新声明一个新的 FileReader 实例,进行读取文件操作,不进行干扰。

  • 情况二
file.onchange = (fileChoosed) => {
    const reader = new FileReader()
    
    for (const fileChoosedItem of fileChoosed.target.files) {
        
        
        setTimeout(() => {
            reader.readAsDataURL(fileChoosedItem)
        })
        
    }
    
    reader.onload = (readResult) => {
      console.log(readResult.target.result)
    }
    
    
}

上述代码执行时,将同步读取变为异步读取,不会阻塞当前 readAsDataURL,可正常运行

  • 情况三
file.onchange = (fileChoosed) => {
    const reader = new FileReader()
    
    for (const fileChoosedItem of fileChoosed.target.files) {
        
        
        setTimeout(() => {
            reader.readAsDataURL(fileChoosedItem)
        })
        
    }
    
    reader.onload = (readResult) => {
      console.log(readResult.target.result)
    }
    
    
}