【问题标题】:Multer req.file is always undefined despite file object created尽管创建了文件对象,但 Multer req.file 始终未定义
【发布时间】:2020-04-29 00:19:42
【问题描述】:

我已经阅读了与此相关的所有问题,但没有任何效果。我花了一整天的时间来解决这个问题。

我正在尝试使用 React、mongoose、mongoDB 和 express/node 将文件上传到我的数据库。

这是我已经做过的:

  • 在我的表单中添加了 method="post"enctype="multipart/form-data"
  • 文件输入的“name”属性是“icon”,在中间件中也是upload.single("icon")

在提交时,我有一个被调用的函数操作。

export const updateUserIconette = icon => async dispatch => {
    console.log("Number 1");
    console.log(icon);
    try {
        const res = await axios.post("/me", icon);
        dispatch({
            type: UPDATE_PROFILE_SUCCESS,
            payload: res.data
        });
    } catch (err) {
        const errors = err.response.data.errors;
        if (errors) {
            errors.forEach(error => dispatch(setAlert(error.msg, "danger")));
        }
        dispatch({
            type: UPDATE_PROFILE_ERROR
        });
    }
};

这里是console.log 1号日志和icon的日志,也是一个文件对象。

API Post 路由在这里:

const multer = require("multer");
const storage = multer.diskStorage({
    destination: function(req, file, callback) {
        callback(null, "./uploads/");
    },
    filename: function(req, file, callback) {
        callback(null, file.originalname);
    }
});
const fileFilter = (req, file, callback) => {
    if (file.mimetype === "image/jpeg" || file.mimetype === "image/png") {
        callback(null, true);
    } else {
        callback(null, false);
    }
};
const upload = multer({ storage: storage, fileFilter: fileFilter });

router.post(
    "/",
    [
        auth,
        upload.single("icon")
    ],
    async (req, res) => {

console.log("number 2")
console.log(req.file)
        // Build the Profile object
        const profileFields = {};
        profileFields.user = req.user.id;
        if (req.body.username) profileFields.username = req.body.username;
        if (req.body.bio) profileFields.bio = req.body.bio;
        if (req.body.location) profileFields.location = req.body.location;
        if (req.file) profileFields.icon = req.file.path;

        try {
            let user = await User.findOne({ _id: req.user.id });

            if (user) {
                //Update
                user = await User.findOneAndUpdate(
                    { _id: req.user.id },
                    { $set: profileFields },
                    { new: true }
                );
                return res.json(user);
            }
            await user.save();
            res.json(user);
        } catch (err) {
            console.error(err.message);
            res.status(500).send("Server Error");
        }
    }
);

这里,console.log number 2 记录但不记录 req.file,因为它是空的。

【问题讨论】:

  • 你有 github repo 吗?调试起来会更容易。
  • 我们的仓库是私有的,但我刚刚用更准确的代码更新了问题,非常感谢您的回复:)
  • 在上传文件方面有很多活动部分,因此如果没有可重现的示例,这将是一场猜谜游戏。如果可以的话,创建一个精简版本的你所拥有的(同样,精简,不需要样式或任何花哨的东西——只需要包含关于此图标上传的客户端和服务器逻辑)。如果没有,我可以创建一个小型工作存储库,但它可能与您的逻辑不符,并且可能对您没有太大帮助。
  • 如果您同意,我会将您添加到存储库中
  • 嗯,让我们试试这个:我将创建一个小型精简工作回购。没有什么花哨。然后,您可以将其用作项目的参考点。我将使用您在问题标签中列出的所有内容。如果在查看我的代码后没有帮助,那么您可以将我添加到您的存储库中。

标签: reactjs mongodb express mongoose multer


【解决方案1】:

好的,这是一个使用 reactmulterexpressmongodbmongoose 的工作演示。这不是花哨的,几乎是赤裸裸的,但它确实有效。您应该做的是逐步完成您的项目,并确保每个文件/函数/中间件都按流程中的预期工作(请参见下面的流程示例)。

Github 仓库https://github.com/mattcarlotta/upload-image-example


按照README 获取有关如何运行它的说明。

所有重要的文件都会有关于它们的功能的注释。

要关注的文件

流程

  • 用户添加文件(图像)和电子邮件地址,然后单击Submit 以向 API 发送POST 请求。
  • POST 请求首先通过 multer 中间件
  • 如果有效,则通过上传图标路由处理请求。
  • 路由将其传递给 saveIcon 中间件
  • saveIcon 中间件将图像保存到uploads,然后将请求传递给createIcon 控制器
  • 控制器将emailicon文件路径保存到mongodb数据库,然后将响应(messageremoteicon)发送回客户端表单
  • 客户端表单从 API 接收res(响应)并将其设置为状态
  • 当状态更新时,remoteicon 被设置为 srcimg 元素,然后向 API 发出 GET 请求,API 反过来将上传的图像发回.

理想情况下,这个流程的大部分将是一个微服务(而不是附加到您的主应用程序),因为它将大大简化您的结构。更多信息可以在here找到。

【讨论】:

    猜你喜欢
    • 2016-06-21
    • 2019-04-04
    • 2017-03-29
    • 2018-08-06
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 2021-10-02
    • 2022-01-18
    相关资源
    最近更新 更多