这个问题把我难住了。我的应用程序需要上传一个包含要在平台上添加/修改等内容的 excel 文件。为此,我需要 Multer 上传 excel 文件,我会将其存储在 os.tempdir()
中以供阅读。
问题:
使用建议的方法和替代方法,我无法通过浏览器将文件上传到我的应用程序(在本地运行)。我尝试过使用 .single("input file name here") 将文件放在 req.file
中的方法,或使用 any() 将文件放在 req.files
中的方法。这些都不返回成功的文件上传,因此 req.file
始终为 undefined
,而 req.files
始终为 []
。
我有什么代码?
您会在下面找到我的网页和服务器端代码:
网页(玉)
...
form(action=`/companies/${companyId}/employees/upload` enctype="multipart/form-data" method="post")
input(type="file", accept=".xlsx,.xls" , name="uploadEmployees", style="background: transparent" required)
input(type="hidden" name="test" value="test")
button#submitUpload.btn.btn-primary(type='submit') Save changes
...
注意事项:
companyId
已在我的 jade 模板中定义,因此操作 URL 完整且正确enctype
类型正确,文件上传应该always use multipart/form-datainput
的 type=file
字段必须具有 name 属性,正如您将看到的,在我的 multer.single("name here")
服务器端代码中正确指定。hidden
的 input
name=test
字段我添加作为健全性检查,此字段未显示在 req
中服务器端代码:
const multer = require('multer')
const uploadSpreadsheet = multer().any();
// router prefix is /companies
router.post('/:id/employees/upload', (req, res, next) => {
uploadSpreadsheet(req, res, (err) => {
if (err instanceof multer.MulterError) {
console.log("Multer error")
console.error(err);
} else if (err) {
console.log("Another error")
console.log(err)
} else {
console.log("Multer function success, next()")
next()
}
});
}, async (req, res, next) => {
console.log("Using multer.any()")
console.log("req.files should not be empty")
console.log(`${req.files ? (req.files.length > 0 ? "req.files has some files" : "req.files has no files") : "req.files is undefined"}`)
console.log(`We should expect to find a hidden field named 'test' with value 'test'`)
console.log(`${req.body === {} ? "req.body is empty" : req.body["test"] ? "hidden field found" : "no hidden field named 'test' found"}`)
console.log(req.body);
if (!req.file || req.file === "") {
req.flash("message", [{
status: false,
message: "No file uploaded or upload failed"
}]);
return res.redirect(`/companies/${req.params.id}/employees`)
}
// read the entire file
const workbook = new ExcelJS.Workbook();
await workbook.xlsx.readFile(req.file);
...
注意事项:
uploadSpreadsheet(req, res...)
部分。这总是next()
,没有任何错误。req.file || req.file === ""
时,它总是失败并重定向。 req.file
和 req.files
始终分别为 undefined 或 []
。控制台输出:
i functions: Beginning execution of "us-central1-app"
> Multer function success, next()
> Using multer.any()
> req.files should not be empty
> req.files has no files
> We should expect to find a hidden field named 'test' with value 'test'
> no hidden field named 'test' found
> [Object: null prototype] {}
由于 Multer function success, next()
行出现,您应该期望在 req.files
或 req.file
中找到文件,但这不会发生。
对于解决此问题的任何帮助,我们将不胜感激!
多单文件上传(为了完整起见)
我在下面定义了我的单个文件上传功能和参数:
const os = require('os')
const tmp = os.tmpdir();
function fileFilter(req, file, cb) {
// for testing
cb(null, true);
}
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, `${tmp}`)
},
filename: function (req, file, cb) {
cb(null, v4())
}
})
// const uploadSpreadsheet = multer({storage: storage, fileFilter: fileFilter}).single("uploadEmployees");
在post路由中,这是使用我的单文件上传时的样子:
router.post('/:id/employees/upload', uploadSpreadsheet, async (req, res, next) => {
...
通过以上这些服务器端代码更改,客户端代码保持不变