【问题标题】:File upload to server using NodeJs and Multer使用 NodeJs 和 Multer 将文件上传到服务器
【发布时间】:2022-01-30 06:45:42
【问题描述】:

我正在尝试使用 NodeJs 和 Multer 将文件上传到服务器。但我不成功。当我从前端发布文件时,我得到如下条件语句:

You must select at least 1 file.

console.log(req.files) 根据下面的脚本返回一个空数组[]

这里是userController.js下面

   

const mysql = require('mysql');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const { promisify } = require('util');
const upload = require("../middleware/upload");
    
    
exports.update = async (req, res) => {
    message = '';
    if (req.method == 'POST') {
        var post = req.body;
        var first_name = post.first_name;
        var last_name = post.last_name;


        if (req.files) {
            //    console.log(req.files)


            try {
                await upload(req, res);
                console.log(req.files);

                if (req.files.length <= 0) {
                    return res.send(`You must select at least 1 file.`);
                }

                return res.send(`Files has been uploaded.`);
            } catch (error) {
                console.log(error);

                if (error.code === "LIMIT_UNEXPECTED_FILE") {
                    return res.send("Too many files to upload.");
                }
                return res.send(`Error when trying upload many files: ${error}`);
            }

这是我的中间件upload.js

 
const util = require("util");
const path = require("path");
const multer = require("multer");

var storage = multer.diskStorage({
  destination: (req, file, callback) => {
    callback(null, path.join(`${__dirname}/../../upload`));
  },
  filename: (req, file, callback) => {
    const match = ["image/png", "image/jpeg", "application/pdf"];

    if (match.indexOf(file.mimetype) === -1) {
      var message = `<strong>${file.originalname}</strong> is invalid. Only accept png/jpeg/pdf.`;
      return callback(message, null);
    }

    var filename = `${Date.now()}-bezkoder-${file.originalname}`;
    callback(null, filename);
  }
});

var uploadFiles = multer({ storage: storage }).array("multi-files", 10);
var uploadFilesMiddleware = util.promisify(uploadFiles);
module.exports = uploadFilesMiddleware;
这是我的user.js 路由:
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');

   router.post('/editcrew/:id',userController.update);

还有我的前端:

<form class="row g-1 needs-validation" method="POST" action="/editcrew/{{this.id}}" encType="multipart/form-data" novalidate>
</form>
<input type="file" name="covid_19D" id="file_box" />

<div class="col-md-1 mt-5 d-grid">
  <button class="btn btn-primary" type="submit">Submit</button>
</div>

非常感谢任何关于正确路径的建议、建议和方向,谢谢!!

【问题讨论】:

    标签: javascript node.js multer


    【解决方案1】:

    您的文件输入在表单之外,因此它不是表单提交时发送内容的一部分。

    将其移至表单中:

    <form class="row g-1 needs-validation" method="POST" action="/editcrew/{{this.id}}" encType="multipart/form-data" novalidate>
      <input type="file" name="covid_19D" id="file_box" />
    </form>
    

    我应该提到,提交按钮很可能也应该进入表单标签,但是由于您仍然设法提交表单,我假设您已经有一些其他代码来处理表单的提交......

    【讨论】:

    • 那不会修复它,检查我更新的答案
    • @traynor 你确定吗? OP 写道,他们收到消息“您必须选择至少 1 个文件”。它来自if (req.files) 条件内部,因此该条件必须已经为真,删除它不会改变任何事情。
    • 表格你说的没错,还有上传中间件有错误,文件名不对,应该是.array("covid_19D", 10);。问题在于上传,它使用util.promisify,它没有返回正确..
    • 不,很好,只需要先调用中间件,我迷路了,因为代码被截断了..
    【解决方案2】:

    更改 HTML 表单(在表单中添加提交按钮和其他字段):

    <form class="row g-1 needs-validation" method="POST" action="/editcrew/{{this.id}}" encType="multipart/form-data" novalidate>
        <input type="file" name="covid_19D" id="file_box" />
        <div class="col-md-1 mt-5 d-grid">
            <button class="btn btn-primary" type="submit">Submit</button>
        </div>
    </form>
    

    在upload.js中添加正确的字段名(与表单中指定的文件字段名相同):

    var uploadFiles = multer({ storage: storage }).array("covid_19D", 10);
    

    在userController.js中,先调用上传中间件,然后检查req.files,同时将req.body变量也移到那里:

    const upload = require("./upload");
    
    
    exports.update = async(req, res) => {
    
        if (req.method == 'POST') {
    
            try {
    
                await upload(req, res);
    
                var post = req.body;
                var first_name = post.first_name;
                var last_name = post.last_name;
    
                if (req.files.length <= 0) {
                    return res.send(`You must select at least 1 file.`);
                }
    
                return res.send(`Files has been uploaded.`);
    
            } catch (error) {
    
                if (error.code === "LIMIT_UNEXPECTED_FILE") {
                    return res.send("Too many files to upload.");
                }
                return res.send(`Error when trying upload many files: ${error}`);
            }
        }
    }
    

    【讨论】:

    • @CherryDT 正确,我发帖后就想到了 :)
    • 您好,我按照上面的方法修改了脚本。但没有成功。该文件从前端正确链接到后端。在userController.js 中,当我在exports.update = async (req, res) =&gt; { 下方插入console.log(req.files) 时,它会为我提供来自前端name 字段的整个covid_19D 对象。当我将console.log(req.files) 放在await upload(req, res); 下时,输出仍然是一个空数组[]。一定是我在 upload.js 中间件上缺少的东西。
    • @CesareMannino 听起来你已经在从其他地方调用上传了.. 检查路由器
    猜你喜欢
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多