问题 解析图像时出现严重错误 NodeJS Express MongoDB

Issue Parsing image with Formidable Error NodeJS Express MongoDB

我遇到了这个问题,我以前从未遇到过这个问题,而且我使用相同的功能上传图像并将其保存到 MongoDB 中已经很久了。这是我使用的函数:

router.post("/profile-pic/:id", async (req, res, next) => {
    try {
        let user = await User.findById(req.params.id);
        if (!user) return res.status(404).send("User not found...");
        let form = new formidable.IncomingForm();
        form.keepExtensions = true;
        form.parse(req, async (err, fields, files) => {
            if (err) return res.status(400).send("Image could not be uploaded.");
            else if (files.profilePic) {
                if (files.profilePic.size > 1000000) {
                    return res.status(400).send("Image can not be larger than 1MB");
                }
                await User.findByIdAndUpdate({ _id: user.id }, {
                    profilePic: {
                        data: fs.readFileSync(files.profilePic.path),
                        contentType: files.profilePic.type
                    }
                }, { useFindAndModify: false });
                res.send("Image uploaded successfully.");
            }
        });
    } catch (ex) {
        console.error(ex);
        next();
    }
});

这是我开始遇到的错误:

(node:10084) UnhandledPromiseRejectionWarning: CastError: Cast to Buffer failed for value "{
  data: <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 02 00 00 01 00 01 00 00 ff ed 00 9c 50 68 6f 74 6f 73 68 6f 70 20 33 2e 30 00 38 42 49 4d 04 04
00 00 00 00 00 80 ... 68443 more bytes>,
  contentType: 'image/jpeg'
}" at path "profilePic"
    at model.Query.exec (C:\Users\Lenovo\Desktop\InstaCringe\server\node_modules\mongoose\lib\query.js:4351:21)
    at model.Query.Query.then (C:\Users\Lenovo\Desktop\InstaCringe\server\node_modules\mongoose\lib\query.js:4443:15)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:10084) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:10084) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will
terminate the Node.js process with a non-zero exit code.

编辑 用户模式:

const userSchema = new mongoose.Schema({
    name: { type: String, trim: true, required: true, maxLength: 60 },
    email: { type: String, unique: true, trim: true, maxLength: 100 },
    password: String,
    isAdmin: { type: Boolean, default: false },
    profilePic: { type: Buffer, contentType: String },
    photos: Array
});

谁能帮我破解这个案子...我不知道为什么我不能再上传图片了。 提前致谢! :)

出现错误的原因:

您的架构中的内容与您试图保存在数据库中的内容不匹配。具体来说,profilePic 在您的架构中定义为:

profilePic: { type: Buffer, contentType: String }

请注意,mongoose 会忽略 contentType 属性,因为它不是 Buffer.
类型的有效选项 为什么 mongoose 考虑 contentType 一个选项? 您可能会问;这是因为当 Mongoose 在您的模式中找到一个名为 type 的嵌套 属性 时,Mongoose 假定它需要定义一个具有给定类型的 SchemaType,并且对象中的每个其他 属性 都被认为 SchemaType options for that type. You can read more about the type key here.

在您的 post /profile-pic/:id 端点中,您正在尝试保存此内容:

profilePic: {
  data: fs.readFileSync(files.profilePic.path),
  contentType: files.profilePic.type
}

Mongoose 会尝试将您尝试保存的对象转换为模式(缓冲区)中指定的对象,但是,它无法做到这一点,这就是您获得 CastError 的原因。

修复:

  1. 如果这是一个选项,删除架构中的 contentType 属性 并直接保存 Buffer 值将是一个简单的解决方法。模式变成这样:
profilePic: { type: Buffer }

然后储蓄变成这样:

profilePic: fs.readFileSync(files.profilePic.path),

现在,profilePic 将保存图像的缓冲区值。

  1. 但是,我猜你之所以有一个 contentType 属性 首先是故意存储缓冲区值的 contentType,如果你仍然对此感兴趣的话一块数据,你将不得不更新你的模式来为它创建一个 space,像这样:
profilePic: { 
  data: { type: Buffer },
  contentType: String 
}

请注意,与之前不同的是,contentType 没有声明为类型 Buffer 的选项,而是一个嵌套的 属性 具有自己的类型。

现在,您可以像之前一样继续保存 profilePic 数据:

profilePic: {
  data: fs.readFileSync(files.profilePic.path),
  contentType: files.profilePic.type
}