[英]Formidable: Parse multipart/form-data request THEN upload file
從昨天開始,我的 node express 應用程序出現了問題。
我想做的是下一個:
中間件 1,步驟 1(解析請求):使用 formidable 解析 req.body 中的 multipart/form-data 並執行我想對數據執行的操作(例如驗證),如果一切正常,則 go 到步驟 2。
中間件2,第2步(上傳文件):使用formidable上傳文件(已解析)
問題:
我知道有一個過濾器 function 但我真的想要兩個獨立的中間件。
快遞中間件
const formidable = require('formidable');
// parse request
module.exports.middleware1 = async (req, res, next) => {
const form = formidable({ multiples: true });
form.parse(req, (err, fields, files) => {
if (err) {
next(err);
return;
}
// request parsed
// do what I want to do with the fields (such validation)
console.log(fields)
next()
});
}
// upload file
module.exports.middleware2 = async (req, res, next) => {
const options = {
uploadDir: 'test',
keepExtensions: true,
maxFiles: 1,
filename: function (name, ext, part, form) {
return name
},
filter: function ({name, originalFilename, mimetype}) {
return true
}
}
const form = formidable(options);
form.parse(req, (err, fields, files) => {
if (err) {
next(err);
return;
}
// file uploaded, go to controller
next()
});
}
前端應用
publishPost: function () {
let formData = new FormData()
const post = {
filters: {
...this.postFilters
},
details: {
...this.postDetails
}
}
formData.append('post', JSON.stringify(post))
formData.append('file', this.postMedia.file)
postService.createOne(formData).then((res) => {
if (res) {
postServiceStatus.createOneDone()
}
});
}
如果有人有想法,我將不勝感激!
我終於找到了解決問題的方法!
我創建了一個全局錯誤處理程序來處理我的 API 上的所有錯誤,當錯誤與我創建文件的路徑相關時(在第一個中間件中),我刪除了包含在 req.file 中傳遞的信息的文件。
const fs = require('fs')
const { DEFAULT_API_PATH } = process.env
/**
* Handle middlewares errors
* @param {Object} err error object
* @param {String} err.type type of error (service affected by the error)
* @param {String} err.error original error
* @param {String} err.message returned error
* @param {Number} err.status error status
* @returns
*/
module.exports = async (err, req, res, next) => {
if (err.error) console.log(err.error)
// Delete file
if (req.path === `${DEFAULT_API_PATH}/posts/create` && req.file) {
if (fs.existsSync(req.file.path)) {
fs.unlinkSync(req.file.path, function (err) {
console.log(err)
});
}
}
if (err.type && err.type === 'database') return res.status(err.status || 400).send({ error: err.message || 'Une erreur innatendue s\'est produite avec la base de données. Veuillez réessayer dans un instant.' })
else if (err.type && err.type === 'server') return res.status(err.status || 400).send({ error: err.message || 'Une erreur innatendue s\'est produite avec le serveur. Veuillez réessayer dans un instant.' })
return res.status(err.status || 400).send({ error: err.message || 'Une erreur innatendue s\'est produite. Veuillez réessayer dans un instant.' })
}
服務器只能使用一次傳入請求,因為請求正文由客戶端流式傳輸,並且 HTTP 協議不允許服務器向客戶端請求“倒帶”。
multer
和formidable
的想法是在使用請求時將文件寫入uploadDir
。 如果您不想在第一個中間件中執行此操作,則需要將文件存儲在 Javascript 變量(例如res.locals.uploadedFile
)中,然后在第二個中間件中自行將其寫入uploadDir
。 但是這樣做有什么好處呢? 主要 memory 比磁盤空間更昂貴。
為什么你堅持使用兩個獨立的中間件?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.