Express & Multer 不上传文件单个/任何导致 req.file/req.files 未定义或 []

时间:2021-07-15 01:35:17

标签: javascript node.js express upload multer

这个问题把我难住了。我的应用程序需要上传一个包含要在平台上添加/修改等内容的 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-data
  • 方法正确,我在发数据
  • 带有 inputtype=file 字段必须具有 name 属性,正如您将看到的,在我的 multer.single("name here") 服务器端代码中正确指定。
  • 带有 hiddeninput 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 错误处理 here - 请参阅上面的 uploadSpreadsheet(req, res...) 部分。这总是next(),没有任何错误。
  • 当点击 req.file || req.file === "" 时,它总是失败并重定向。 req.filereq.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.filesreq.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) => {
    ...

通过以上这些服务器端代码更改,客户端代码保持不变

0 个答案:

没有答案