方案一:结合服务端实现
- 将用户所选的图片上传到服务器
- 服务器接收上传的文件保存到服务器并返回服务器上的图片访问地址(http://example.com/a.jpg)
- 客户端将 img 的 src 设置为收到的图片地址
- 优点:兼容性好
- 缺点:麻烦
方案二:纯客户端实现
有两种 HTML5 增加的 API:
- 使用 URL.createObjectURL()
- 创建一个 DOMString,返回一个表示传递的参数对象的 URL,例如:
blob:null/88a6a6a6-9858-4bfe-81ed-c1263cfa0cc8
。 - 这个URL和浏览器窗口的 document 绑定,会随着窗口关闭而释放。
- 所以它会占用内存,如果不释放(
URL.revokeObjectURL
),则有可能导致内存泄露,
- 创建一个 DOMString,返回一个表示传递的参数对象的 URL,例如:
- 【推荐】使用 FileReader
- 真正转换成 Base64 字符串,例如:
data:image/jpeg;base64,/9j/4AAQSkZJ......
- 与浏览器无关,该字符串可以在任何地方使用
- 真正转换成 Base64 字符串,例如:
<input type="file" id="file" />
<img id="img" src="" />
<script>
const file = document.querySelector('#file')
const img = document.querySelector('#img')
// 方式1:URL.createObjectURL()
// file.onchange = () => {
// const data = URL.createObjectURL(file.files[0])
// img.src = data
// // 此方式还需要在安全的时机主动释放,否则占用内存
// // URL.revokeObjectURL(data)
// }
// 方式2:FileReader
file.onchange = () => {
// 不同于 nodejs 的 fs 可以读取磁盘文件,浏览器中的 FileReader 只能操作用户选择的文件
const reader = new FileReader()
// 当图片独去转换完成,会触发 load 事件
reader.onload = () => {
img.src = reader.result
}
// 开始读文件
reader.readAsDataURL(file.files[0])
}
</script>
优点:
- 纯客户端本地实现,简单省事
- 不需要请求,速度快
缺点:
- 兼容性问题