在日常工作中,引用第三方工具是很常见的事。但是如果为了满足某一个需求,而引用一个巨大的工具,而实际情况却是仅仅使用到这个工具所有功能的冰上一角,这是相当没有规划,没有追求的行为。为了告别<a href="http://fex.baidu.com/webuploader/" target="_blank">Web Uploader</a>(当然这是一个很出色的工具),我用这篇文章理一理文件读取与上传的相关知识。
文件读取
首先我们需要一个上传的控件。
如果你嫌弃原生的上传控件颜值不优雅,可以自行用模拟一个,监听点击事件并触发一只隐藏的input[file]。
<!-- 如果需要一次性上传多个图片,可以加上multiple属性 -->
<input id="fileUploadBtn" type="file">
当有文件传入时,会触发onchange
事件
fileUploadBtn.addEventListener('change', callback)
此时我们可以拿到上传的file对象,包含了上传文件的相关信息详情点这儿。
var callback = function () {
var file = this.files[0]
}
FileReader API 提供了四种读取文件方式,名字也取得相当语义化。
var reader = new FileReader()
reader.readAsText(file, encoding)
reader.readAsDataURL(file)
reader.readAsBinaryString(file)
reader.readAsArrayBuffer(file)
reader.readyState
记录着reader的状态。
- 0:new之后
- 1:执行上述四个读取方法之一后
- 2:读取完毕,触发onload事件
reader读取文件是异步操作,主要的生命周期Event和常规异步(如Ajax)很相似。
// 上传进度
reader.onprogress = function (ev) {
if (ev.lengthComputable) { // 文件的长度是否可计算
ev.total // 文件总长
ev.loaded // 已加载
}
}
// 上传成功
reader.onload = function () {
reader.result // 文件信息
}
// 上传失败
reader.onerror = function () {
reader.error // 错误信息
}
// 上传完成
reader.loadend = function () {}
// 上传开始
reader.loadstart = function () {}
构造FormData及Ajax上传文件
在前后端分离与Ajax大行其道的今天,我们这一代人多少对 FormData 有些陌生。今天也算是涨见识了。
var callback = function () {
var file = this.files[0]
var xhr = new XMLHttpRequest()
// new一个FormData实例
var formData = new FormData()
// 将file对象添加到FormData实例
formData.append('file', file)
xhr.open('POST', 'url', true)
xhr.send(formData)
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// doSomeThing(this)
} else {
// error(this)
}
}
}
}