Javascript 从Node.js和Mongoose中的二进制文件重新创建图像
我正在Node.js中创建上传/下载图像功能。到目前为止,有一个POST请求将图像保存为MongoDB中的二进制文件,还有一个GET请求将图像返回。但我不知道如何使用这个响应,它是一个数字数组,不知道如何转换它 以下是Mongo模型: image.js const mongoose=require('mongoose'); const Schema=mongoose.SchemaJavascript 从Node.js和Mongoose中的二进制文件重新创建图像,javascript,node.js,mongodb,rest,mongoose,Javascript,Node.js,Mongodb,Rest,Mongoose,我正在Node.js中创建上传/下载图像功能。到目前为止,有一个POST请求将图像保存为MongoDB中的二进制文件,还有一个GET请求将图像返回。但我不知道如何使用这个响应,它是一个数字数组,不知道如何转换它 以下是Mongo模型: image.js const mongoose=require('mongoose'); const Schema=mongoose.Schema const ImageItem = new Schema({ id: { type: String
const ImageItem = new Schema({
id: {
type: String
},
value: {
type: Buffer
},
});
module.exports = Image = mongoose.model('image', ImageItem);
在DB中创建条目的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,
});
});
});
};
以及在DB中创建的条目:
为了获取图像,我创建了一个获取请求:
const image=require('../models/image')
在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
}
]
如何使用此数据获取实际图像?您可以从该数组创建一个
缓冲区
const imageBuffer = Buffer.from(row.value.data); // [117, 112, 108...]
在任何情况下,检查您的ImageItem
架构时,row.value
将成为一个缓冲区
const { mime } = fileType(row.value)
现在,您需要做的就是设置正确的内容类型
,并使用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);
}
});
});
如果您不知道内容类型
,可以使用文件类型
包从缓冲区中获取它
const { mime } = fileType(row.value)
由于您只获取特定图像,因此可能需要使用.findOne
而不是.find
现在还有另一个问题,您存储的是文件路径,而不是您想要的二进制图像
您发布的字节等于:uploads/userPicture.png2020-05-14T10:23:13.934Z“
const data=new textdecker().decode(新的UINT8数组([117111081111,97100115,471171110114,80105,991161114101,46112110103,50,48,50,48,45,45,52,84,49,48,58,50,51,58,49,51,51,52]))
console.log(data);
当您将图像发送到客户端时,mongoose调用方法“toJSON”,默认情况下,缓冲区JSON对象如您所示。您可以覆盖mongoose方案的toJSON方法(此处您找到信息-),服务器将返回图像的base64表示形式
const mongoose=require(“mongoose”),
Schema=mongoose.Schema;
var imageSchema=新模式({
数据:{
类型:缓冲区,
要求:正确,
},
类型:{
类型:字符串,
要求:正确,
},
});
set(“toJSON”{
虚拟人:是的,
versionKey:false,
转换:功能(文档、ret){
const base64=doc.data.toString(“base64”);
ret.data=`data:image${doc.type};base64,${base64}`;
返回ret;
},
});
module.exports=mongoose.model(“图像”,imageSchema)
第一行的const image
应该放在哪里?将其重命名为imageBuffer
,以避免冲突。正如您在第二个代码段中看到的,它放在路由上。首先感谢您的回复,但它目前不起作用。我将该代码放在Postman中,它返回以下错误消息:Proxy错误:无法代理请求/上载/email122345@test.com从localhost:3000到http://localhost:5000 (EconReset)。
。我正在使用nodemon从客户端和服务器上运行我的应用程序。尝试获取映像后,服务器崩溃:TypeError[ERR\u INVALID\u ARG\u TYPE]:第一个参数的类型必须为string或Buffer、ArrayBuffer、Array或类似数组的对象的实例。接收到未定义的
,在客户端显示:代理错误:无法代理请求/上载/email122345@test.com从localhost:3000到http://localhost:5000. 看见https://nodejs.org/api/errors.html#errors_common_system_errors以获取更多信息(ECONNRESET)。
我在服务器上使用5000,在客户端使用3000,那么您没有将数组传递到缓冲区。from