Tengo pequeñas miniaturas almacenadas en una colección de MongoDB. Si bien puedo extraerlos con un .findOne() , no puedo devolverlos a través de una ruta ExpressJS correctamente.
No estoy almacenando miniaturas en el disco ya que el entorno heroku no garantiza el almacenamiento persistente. No estoy usando GridFS ya que estos son miniaturas <16 MB.
Insertar un nuevo documento en la colección es algo como esto:
MongoClient.connect(url, function(err, db){ var newImg = fs.readFileSync(req.file.path); var encImg = newImg.toString('base64'); var newItem = { description: req.body.description, date: Date(), contentType: req.file.mimetype, size: req.file.size, img: Buffer(encImg) }; db.collection('myimages') .insert(newItem, function(err, result){ if (err) { console.log(err); } }); }); Puedo servir el img a través de una ruta Expressjs como esta:
router.get('/pictures/:picture', function(req, res){ /* my filename is actually a mdb oid */ var filename = req.params.picture; MongoClient.connect(url, function(err, db){ db.collection('myimages') .findOne({'_id': ObjectId(filename)}, function(err, results){ console.log(results); //<-- Output below res.setHeader('content-type', results.contentType); res.send(results.img); }); }); }); El nodejs console.log devuelve un objeto como este,
{ _id: 58f7ab923b7c842023cf80ec, description: '', date: 'Wed Apr 19 2017 13:25:22 GMT-0500 (CDT)', contentType: 'image/jpeg', size: 648436, img: Binary { _bsontype: 'Binary', sub_type: 0, position: 864584, buffer: <Buffer 2f 39 6a 2f 34 41 41 51 53 6b 5a 4a 52 67 41 42 41 51 41 41 53 41 42 49 41 41 44 2f 34 51 50 38 52 58 68 70 5a 67 41 41 54 55 30 41 4b 67 41 41 41 41 ... > } }Pero la consola del navegador me da un error como este:
Resource interpreted as Document but transferred with MIME type image/jpeg: "http://localhost:3000/picturewall/58f7ab923b7c842023cf80ec". ¿Estoy descodificando incorrectamente? ¿Configuración incorrecta de los encabezados res ?
¿Puede alguien mostrarme lo que estoy haciendo mal?
Entonces parece que guardaste una imagen base64 en tu base de datos.
Lo haces así img: Buffer(encImg) . En node.js, la codificación de búfer predeterminada es utf8 , por lo que su imagen se guarda en db como una cadena base64 utf8 en tipo binario en MongoDB.
Una forma adecuada será especificar una codificación de búfer cuando guarde su imagen:
// ... img: Buffer.from(encImg, 'base64') // ... De esa manera, cuando envíe una respuesta al cliente como res.send(results.img.buffer); enviará datos binarios en lugar de una cadena base64.