属性files的类型是FileList
,一个类数组,由浏览器通过用户行为往里面添加或删除元素,JS只有访问接口,无法操作。而files的元素就是File
类型,File是blob
的子类,比blob主要多出一个name的属性。
该元素只是一个指向文件系统的引用,如果想要取到这个文件的备份,就需要通过FileReader
把数据读出来保存在浏览器中。
readAsArrayBuffer=>
ArrayBuffer
- 二进制数据的存储器,可通过ArrayBufferView以8位、16位、32位、64位数字为元素对ArrayBuffer内的二进制数据进行展现。
- 可用于生成Blob,然后添加到FormData去上传。
readAsBinaryString =>
BinaryString
- 是二进制数据直接以byte的形式展现的字符串,ArrayBuffer对应的Uint8Array的字符形式的表现
readAsDataURL =>
DataURL
- 包括mimeType和base64编码后的binaryString,可以直接给<img src="">使用:
data:[mimeType];base64,[base64(binaryString)]- 可借此获取mimeType和binaryString
var binaryString = atob(dataUrl.split(',')[1]),
mimeType = dataUrl.split(',')[0].match(/:(.*?);/)[1];
截图上传的一个完整流程:
- canvas截图并使用toDataURL,获取
DataURL
- 通过binaryString = atob(dataUrl.split(',')[1])获取
BinaryString
- 通过Uint8Array和charCodeAt把binaryString转化为
ArrayBuffer
- ArrayBuffer存入Blob并添加到FormData上传,服务器最终收到
BinaryString
注意,formdata在send时必须使用ArrayBuffer,因为BinaryString为字符串,当send发送时会对字符串进行utf8编码导致数据被破坏。
一个预览并上传图片的demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form name='test'>
<input type="file" name='file'>
<input type="submit" value="提交">
</form>
<img src="" alt="">
<script>
var img = document.querySelector('img'),
preview;
document.test.file.addEventListener('change', function() {
var fr = new FileReader();
fr.onload = function() {
preview = this.result;
img.src = preview;
};
fr.readAsDataURL(this.files[0]);
})
document.test.addEventListener('submit', function(e) {
e.preventDefault();
var binaryString = atob(preview.split(',')[1]),
mimeType = preview.split(',')[0].match(/:(.*?);/)[1],
length = binaryString.length,
u8arr = new Uint8Array(length),
blob,
fd = new FormData(),
xhr = new XMLHttpRequest();
while(length--) {
u8arr[length] = binaryString.charCodeAt(length);
}
blob = new Blob([u8arr.buffer], {type: mimeType});
fd.append('file', blob);
xhr.open('post', '/upload');
xhr.send(fd);
})
</script>
</body>
</html>
也可以把ArrayBuffer缓存入Blob,通过websocket给img一个url进行预览
reader.readAsArrayBuffer(imgs.files[0]);
reader.onload=function(e){
var bf = this.result;
var blob = new Blob([bf],{type:"text/plain"});
img.src = URL.createObjectURL(blob);
}
var bytes = new Uint8Array()可以接受一个length,或bufferArray作为参数