尽管创建了文件对象,但 Multer req.file 始终未定义

Posted

技术标签:

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

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

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


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

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

要关注的文件

client-side form(具体发FormDatahere) multer middleware upload icon route saveIcon middleware createIcon controller

流程

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

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

【讨论】:

以上是关于尽管创建了文件对象,但 Multer req.file 始终未定义的主要内容,如果未能解决你的问题,请参考以下文章

反应节点通过 axios 传递文件与 multer 错误 500

如何使用 multer 存储具有文件扩展名的文件?

使用 multer 上传多个文件,但来自不同的字段?

我尝试从 multipart api 上传文件和文本数据,但即使我使用 multer 也无法获取文件

multer创建文件夹,如果不存在

如何在multer中检查文件类型