javascript - 在 Node.js 和 Mongoose 中从二进制重新创建图像

标签 javascript node.js mongodb rest mongoose

我正致力于在 Node.js 中创建上传/下载图像功能。到目前为止,有一个将图像以二进制形式保存在 MongoDB 中的 POST 请求,还有一个返回该图像的 GET 请求。但我不知道如何使用该响应,它是一个数字数组,不知道如何转换它。

这是 Mongo 模型:

image.js const mongoose = require(' Mongoose '); const Schema = mongoose.Schema;

const ImageItem = new Schema({
  id: {
    type: String
  },
  value: {
    type: Buffer
  },
});

module.exports = Image = mongoose.model('image', ImageItem);

在数据库中创建条目的 POST 图像:

const image = require('../models/image');
const user = require('../models/user');

const multer = require('multer');
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './uploads/');
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname + new Date().toISOString());
  },
});


const upload = multer({
  storage: storage,
});

module.exports = function (app) {
  app.post('/upload', upload.single('value'), (req, res, next) => {
    const newImage = new image({
      id: req.body.id,
      value: req.file.path,
    });
    newImage
      .save()
      .then((result) => {
        console.log(result);
        res.status(201).json({
          message: 'created succesfully',
        });
      })
      .catch((err) => {
        console.log(err);
        res.status(500).json({
          error: err,
        });
      });
  });
};

以及在数据库中创建的条目:

enter image description here

为了获取图像,我创建了一个 GET 请求:

const image = require('../models/image');

module.exports = function (app) {
  app.get('/upload/:id', (req, res) => {
    console.log('req.body.id', req.params);
    image.find({ id: req.params.id }, function (err, results) {
      if (err) {
        res.send(`error: ${err}`);
      } else {
        res.send(results);
      }
    });
  });
};

在 Postman 中测试返回一个包含数字数组的 JSON:

[
    {
        "_id": "5ebd1c112892f4230d2d4ab4",
        "id": "email123@test.com",
        "value": {
            "type": "Buffer",
            "data": [
                117,
                112,
                108,
                111,
                97,
                100,
                115,
                47,
                117,
                115,
                101,
                114,
                80,
                105,
                99,
                116,
                117,
                114,
                101,
                46,
                112,
                110,
                103,
                50,
                48,
                50,
                48,
                45,
                48,
                53,
                45,
                49,
                52,
                84,
                49,
                48,
                58,
                50,
                51,
                58,
                49,
                51,
                46,
                57,
                51,
                52,
                90
            ]
        },
        "__v": 0
    }
]

我如何使用这些数据来获取实际图像?

最佳答案

您可以创建一个 Buffer来自那个数组。

const imageBuffer = Buffer.from(row.value.data); // [117, 112, 108...]

无论如何检查你的ImageItem模式,row.value将是 Buffer .

现在您需要做的就是设置正确的 content-type并回复Buffer使用 res.send 而不是 Mongoose 模式.

app.get('/upload/:id', (req, res) => {
    console.log('req.body.id', req.params);
    image.find({ id: req.params.id }, function (err, results) {
      if (err) {
        res.send(`error: ${err}`);
      } else {
        const [row] = results;
        res.header('Content-Type', 'image/png');
        res.send(row.value);
      }
    });
});

如果您不知道 Content-Type你可以使用 file-typeBuffer 获取它的包.

const { mime } = fileType(row.value)

因为你只得到一个特定的图像,你可能想使用 .findOne而不是 .find


现在您遇到了其他问题,您正在存储文件路径,而不是您想要的二进制图像。

您发布的那些字节等于:uploads/userPicture.png2020-05-14T10:23:13.934Z"

const data = new TextDecoder().decode(new Uint8Array([117,112,108,111,97,100,115,47,117,115,101,114,80,105,99,116,117,114,101,46,112,110,103,50,48,50,48,45,48,53,45,49,52,84,49,48,58,50,51,58,49,51,46,57,51,52]))

console.log(data);

您必须保存实际图像,而不是您的代码工作的文件路径。

const fs = require('fs').promises;
// ....

const newImage = new image({
      id: req.body.id,
      value: await fs.readFile(req.file.path)
});

关于javascript - 在 Node.js 和 Mongoose 中从二进制重新创建图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61795130/

相关文章:

javascript - 直接为原型(prototype)的属性赋值与.extend 的区别

javascript - 无法使简单的 jQuery 工作

javascript - 错误: Can't set headers after they are sent when return jwt.验证

javascript - vue.js - 在我的项目中实现 Auth0 示例给我 _vm.login 不是一个函数(…)

mysql - 处理 mysql 数据库连接

c# - 如何使用 BsonClassMap 配置 ObjectId 数组的表示形式?

php - 将字符串传递到 PHP 中的 Javascript 函数中 - 如何正确转义?

javascript - 脚本5007。 IE7无法读取函数

javascript - 在 mongoDB 中,如何通过_id 找到以前的文档?

python - pymongo 排序和 find_one 问题