javascript - Express & Multer 不上传文件单个/任何导致 req.file/req.files 未定义或 []
问题描述
这个问题把我难住了。我的应用程序需要在平台上上传包含要添加/修改等内容的 excel 文件。为此,我需要 Multer 上传 excel 文件,并将其存储在其中以os.tempdir()
供阅读。
问题:
使用建议的方法和替代方法,我无法通过浏览器将文件上传到我的应用程序(在本地运行)。我尝试过使用.single("input file name here")将文件放入 .single("input file name here") 的方法req.file
,或者将文件放入 .single() 的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
在我的玉模板中定义,因此动作 URL 是完整且正确的enctype
类型正确,应该始终使用 multipart/form-data进行文件上传- 方法正确,我正在发布数据
- 必须有一个 name 属性的
input
字段,正如您将看到的,这在我的服务器端代码type=file
中正确指定。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);
...
笔记:
- 为了检查 Multer 错误,我使用了此处建议的 Multer 错误处理- 请参阅
uploadSpreadsheet(req, res...)
上面的部分。这总是没有next()
任何错误。 - 击中时
req.file || req.file === ""
,它总是失败并重定向。req.file
并且req.files
总是未定义或[]
分别。
控制台输出:
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
任何解决此问题的帮助将不胜感激!
Multer 单文件上传(为了完整起见)
我在下面定义了我的单个文件上传功能和参数:
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");
在发布路线中,这是使用我的单个文件上传时的样子:
router.post('/:id/employees/upload', uploadSpreadsheet, async (req, res, next) => {
...
通过上述这些服务器端代码更改,客户端代码保持不变
解决方案
推荐阅读
- azure-data-catalog - 如何通过 REST API 为 Azure 数据目录资产设置友好名称?
- regex - Apache 重写,包括查询字符串操作
- amazon-web-services - 我们可以在无服务器架构上部署 QlikSense 吗?
- asp.net - 如何解决 ASP.NET MVC 和 sql server 2019 中系统找不到文件指定错误
- java - 从 Java Spring Boot 中的 Principal 中提取数据
- lua - Lua 表被覆盖
- java - 使用真实设备在颤振中调试第一个应用程序时出错
- c++ - TBB 并行管道:过滤器时序不一致
- python - 通过 XML 文件和 netsh wlan(或 Python)更改 wifi 配置文件的密码
- python - 平台问题中无法加载级别列表