后端读取
form 提交
// views
...
<form action="/uploadPath" method="POST" enctype="multipart/form-data">
用户名:<input type="text" name="username">
密 码:<input type="text" name="password">
图片上传1:<input type="file" name="fileName1">
图片上传2:<input type="file" name="fileName2">
<input type="submit" value='提交'>
</form>
...
ajax 提交
...
// 使用 antd4 模拟
const onFinish = values => {
console.log('Success:', values);
// post
};
...
nodejs 模拟读取
const express = require("express");
const app = express();
const path = require('path');
// 1. 第三方模块, 用来处理上传文件 https://www.npmjs.com/package/multer
const multer = require('multer')
// 可以给文件重命名
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'static/upload')
},
filename: (req, file, cb) => {
const {originalname,fieldname } = file
const extname = path.extname(originalname)
cb(null, fieldname+extname)
}
})
const upload = multer({ storage: storage })
route.get("/", (req, res) => {
res.render("home page");
});
// 上传多个文件
const cpUpload = upload.fields([{ name: 'fileName1', maxCount: 1 }, { name: 'fileName2', maxCount: 1 }])
route.post("/uploadPath", cpUpload, (req, res) => {
res.send({
body: req.body,
file: req.files // 上传多个文件,通过 req.files 可以获取上传的文件
});
});
app.listen(3000);
前端读取, 使用 FileReader
1. WebAPI 解释
FileReader : **FileReader**
对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File
或 Blob
对象指定要读取的文件或数据。
File : 通常情况下, File
对象是来自用户在一个 <input>
元素上选择文件后返回的 FileList
对象, File
对象是特殊类型的 Blob
,它的接口继承了 Blob
Blob : Blob
对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取
ArrayBuffer : **ArrayBuffer**
对象用来表示通用的、固定长度的原始二进制数据缓冲区, 要通过类型数组对象或 [DataView](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/DataView)
对象来操作
URL.createObjectURL() : **URL.createObjectURL()**
静态方法会创建一个 [DOMString](https://developer.mozilla.org/zh-CN/docs/Web/API/DOMString)
,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 [document](https://developer.mozilla.org/zh-CN/docs/Web/API/Document)
绑定。这个新的URL 对象表示指定的 [File](https://developer.mozilla.org/zh-CN/docs/Web/API/File)
对象或 [Blob](https://developer.mozilla.org/zh-CN/docs/Web/API/Blob)
对象。
2. FileReader 使用方法
参考: https://www.cnblogs.com/dongxixi/p/11005607.html
方法: 读取文件是异步的
方法定义 | 描述 |
---|---|
abort():void | 终止文件读取操作 |
readAsArrayBuffer(file):void | 异步按字节读取文件内容,结果用ArrayBuffer对象表示 |
readAsBinaryString(file):void | 异步按字节读取文件内容,结果为文件的二进制串 |
readAsDataURL(file):void | 异步读取文件内容,结果用data:url的字符串形式表示 |
readAsText(file,encoding):void | 异步按字符读取文件内容,结果用字符串形式表示 |
事件
事件名称 | 描述 |
---|---|
onabort | 当读取操作被中止时调用 |
onerror | 当读取操作发生错误时调用 |
onload | 当读取操作成功完成时调用 |
onloadend | 当读取操作完成时调用,不管是成功还是失败 |
onloadstart | 当读取操作将要开始之前调用 |
onprogress | 在读取数据过程中周期性调用 |
3. 使用示例
...
// dom
<input type='file' id='note' />
...
<script>
const fileDom = document.querySelector('#note');
var reader = new FileReader();
fileDom.onchange = function() {
const originFileObj = this.files[0]
console.log(fileDom.files)
const reader = new FileReader();
// 1. ArrayBuffer
reader.readAsArrayBuffer(originFileObj);
// 2. Binary
reader.readAsBinaryString(originFileObj);
// 3. DataURL
reader.readAsDataURL(originFileObj);
// 4. Text
reader.readAsText(originFileObj);
reader.onload = (evt) => {
const resultData = evt.target.result
console.log('resultData', resultData)
}
}
</script>
FileList 是个数组,每项是 File 对象 File 对象包括一下内容 lastModified:文件最后一次修改的时间 lastModifiedDate:文件最后一次修改的时间 name:文件名 size: 文件大小 type:文件MIME类型 weblitRelativePath:此处为空;当在input上加上webkitdirectory属性时,用户可选择文件夹,此时weblitRelativePath表示文件夹中文件的相对路径
4. 读取同一张图片结果
readAsArrayBuffer
readAsBinaryString
readAsDataURL
readAsText
5. 应该选择那种方式来读取文件
对于“文件上传器”,您根本不应该使用FileReader。
you can send it as a Blob directly,您无需阅读即可上传文件。
如果需要在当前页面中显示它,则仍然不需要FileReader 通过 create a blobURI from the Blob,它会直接指向磁盘上的文件,而不会浪费大量内存。
inp.onchange = e => {
// yes that's all synchronous...
const url = URL.createObjectURL(inp.files[0]);
const img = new Image();
img.src = url;
document.body.appendChild(img);
};
<input type="file" id="inp" accept="image/*">
FileReader的唯一用例是当您需要访问File的内容时,例如,
如果要加载文本文件(或csv或json)并进行解析,则将使用readAsText()
方法。
如果您想读取/编辑某些二进制文件(例如,读取JPEG文件的元数据?),则可以使用readAsArrayBuffer()
,并从此缓冲区中进行操作。
不幸的是,readAsDataURL()
被滥用太多了,如前所述,在99%的情况下,可以使用blobURI或直接通过Blob完成此dataURI的操作。我能看到的唯一一种情况是在一个独立的文档中附加二进制数据…或者,并不是每个网站每天都发生的事情…readAsBinaryString()
毫无用处,甚至已从标准中删除。如果确实需要File的二进制字符串表示形式,则可以从ArrayBuffer生成一个二进制字符串表示形式,但是使用此String字符串所做的事情是一个谜。 (直接与ArrayBuffer一起使用)。
6. 优雅使用
因为读取文件是异步的,还有浏览器兼容问题,多处用到可以简单封装使用, 调用的时候就可以愉快的使用 async await 了
const FileReaderFn = (fileObj: File | Bolb, type = 'readAsText' ) => {
return new Promise((resolve, reject) => {
if(typeof FileReader === 'undefined') {
reject('您的浏览器不支持读取该文件,请使用谷歌浏览器')
}
const reader = new FileReader();
reader.[type](fileObj);
reader.onload = (evt) => {
const content = evt.target.result;
if (content) {
resolve(content);
}
reject('文件内容有误')
};
reader.onerror(err) => {
reader.abort();
reject(err);
}
});
};
export default FileReaderFn