我正致力于在 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,
});
});
});
};
以及在数据库中创建的条目:
为了获取图像,我创建了一个 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-type
从 Buffer
获取它的包.
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/