node - Cargar imagen de Binary(Javascript-Ajax-MongoDB)
save image mongoose (1)
Tengo una imagen guardada en un MongoDB. El modelo es el siguiente:
picture: {
metadata: {
name: { type: String, default: null },
comment: { type: String, default: null },
publisherID: { type: String,default: null },
date: { type: Date, default: Date.now },
size: { type: Number,default: 0 },
type: { type: String, default: null }
},
data: { type: Buffer, default: null },
tags: Array
}
Ahora necesito cargar la imagen nuevamente desde el DB.
Hago una llamada AJAX y solicito la imagen con la identificación.
$.ajax({
type: "POST",
url: window.location.origin + ''/picture'',
contentType: ''application/json'',
dataType: ''json'',
async: true,
data: JSON.stringify({ id: id }),
success: function (result) {
console.log(result);
a = result;
var img = result.result[0].picture.data.join("").toString(''base64'');
img = "data:" + result.result[0].picture.metadata.type + ";base64," + img;
$(''#img'').attr(''src'', img);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(''error '' + textStatus + " " + errorThrown);
success = false;
}
});
Y este es el controlador en el servidor
var Picture = require(''../models/picture'');
Picture.find({ "_id": req.body.id}, function (err, pic) {
if (err || !pic)
res.end(JSON.stringify({ result: "error" }));
if (pic) {
console.log(pic);
res.end(JSON.stringify({ result: pic }));
}
})
He traducido los datos binarios en base64 pero la imagen no se muestra. (Tuve que unirme a los datos binarios porque entraron en una matriz). Hay algunas otras publicaciones similares, pero no tienen nada que no haya hecho (creo).
Como se indicó en los comentarios, es mejor tener un punto final separado en su aplicación para hacer que estas llamadas se "parezcan" a solicitudes de archivos estáticos estándar. Entonces, lo primero que haría es cambiar un poco tu esquema:
picture: {
metadata: {
name: { type: String, default: null },
comment: { type: String, default: null },
publisherID: { type: String,default: null },
date: { type: Date, default: Date.now },
size: { type: Number,default: 0 },
type: { type: String, default: null }
},
path: { type: String, required: true },
mime: { type: String, required: true },
data: { type: Buffer, default: null },
tags: Array
}
Entonces eso agrega dos campos que identificarán la "ruta" a la imagen para que coincida, y "mime" como el tipo mime del archivo. Así que "ruta" es un identificador más "amigable" que un _id
y el "tipo mímico" se establecerá en insertar para que coincida con el tipo de contenido devuelto.
Luego configura una ruta para servir el contenido:
app.get(''/images/:imgname'', function(req,res) {
Picture.find({ "picture.path": req.param("imgname") }, function(err,pic) {
if (err) // checking here
// Sending response
res.set(''Content-Type'', pic.mime);
res.send( pic[0].picture.data );
});
})
Entonces cuando hiciste una solicitud como:
wget http://localhost:3000/images/test.png
Esto sucedería:
Encuentre la "ruta" de matización del documento para "test.png"
Asigne la propiedad del documento para "picture.mime" como Content-Type para la respuesta
Enviar los datos binarios nuevamente como la respuesta
Entonces, para el cliente, la respuesta es un archivo real, y el punto es que ese "navegador" puede almacenarlo en caché y no afectar a su aplicación donde la copia "en caché" sea válida.
Si está integrando datos codificados en Base64 en respuestas JSON, perderá esa parte importante y enviará los datos en todo momento. También es un proceso muy complicado de manejar, como habrás descubierto.