如何管理存储和处理通过表格上传的文件,在Express中
这是一个HTML表单的例子,允许用户上传文件。
<form method="POST" action="/submit-form" enctype="multipart/form-data">
<input type="file" name="document" />
<input type="submit" />
</form>
不要忘记在表单中添加
enctype="multipart/form-data",否则文件不会被上传
当用户按下提交按钮时,浏览器会自动向页面上同一来源的POST ,并向/submit-form URL发出请求。浏览器发送所包含的数据,不是作为普通表单的编码application/x-www-form-urlencoded ,而是作为multipart/form-data 。
在服务器端,处理多部分数据可能很棘手,而且容易出错,所以我们要使用一个叫做formidable的实用库。这里是GitHub repo,它有超过4000颗星,并且维护良好。
你可以用它来安装。
然后在你的Node.js文件中包含它。
const express = require('express')
const app = express()
const formidable = require('formidable')
现在,在/submit-form 路线上的POST 端点,我们使用formidable.IncomingForm() 来实例化一个新的Formidable表单。
app.post('/submit-form', (req, res) => {
new formidable.IncomingForm()
})
这样做之后,我们需要能够解析这个表单。我们可以通过提供一个回调来同步进行,这意味着所有的文件都会被处理,一旦formidable完成了,它就会让它们可用。
app.post('/submit-form', (req, res) => {
new formidable.IncomingForm().parse(req, (err, fields, files) => {
if (err) {
console.error('Error', err)
throw err
}
console.log('Fields', fields)
console.log('Files', files)
for (const file of Object.entries(files)) {
console.log(file)
}
})
})
或者,你可以使用事件来代替回调。例如,当每个文件被解析时被通知,或其他事件,如文件处理完成,收到一个非文件字段,或如果发生错误。
app.post('/submit-form', (req, res) => {
new formidable.IncomingForm().parse(req)
.on('field', (name, field) => {
console.log('Field', name, field)
})
.on('file', (name, file) => {
console.log('Uploaded file', name, file)
})
.on('aborted', () => {
console.error('Request aborted by the user')
})
.on('error', (err) => {
console.error('Error', err)
throw err
})
.on('end', () => {
res.end()
})
})
无论你选择哪种方式,你都会得到一个或多个Formidable.File对象,这些对象给你上传的文件的信息。这些是你可以调用的一些方法。
file.size, 以字节为单位的文件大小file.path, 文件被写入的路径file.name, 文件的名称file.type, 文件的MIME类型
路径默认为临时文件夹,如果你监听fileBegin 事件,可以修改。
app.post('/submit-form', (req, res) => {
new formidable.IncomingForm().parse(req)
.on('fileBegin', (name, file) => {
file.path = __dirname + '/uploads/' + file.name
})
.on('file', (name, file) => {
console.log('Uploaded file', name, file)
})
//...
})