Come affermato nei commenti, è meglio avere un endpoint separato nell'applicazione per fare in modo che queste chiamate "assomiglino" a richieste di file statici standard. Quindi la prima cosa io non farebbe altro che cambiare un po' il tuo schema:
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
}
In questo modo vengono aggiunti due campi che identificheranno il "percorso" dell'immagine da abbinare e "mime" come tipo mime del file. Quindi "percorso" è un identificatore più "amichevole" di un _id
e il "tipo mime" verrebbe impostato in inserto in modo che corrisponda al tipo di contenuto restituito.
Quindi imposti un percorso per servire il contenuto:
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 );
});
})
Quindi, quando hai fatto una richiesta del tipo:
Questo accadrebbe:
-
Trova il "percorso" di corrispondenza del documento per "test.png"
-
Assegna la proprietà del documento per "picture.mime" come tipo di contenuto per la risposta
-
Invia i dati binari come risposta
Quindi, per il client, è un vero file come risposta, e il punto è che il "browser" può mettere in cache questo e non colpito la tua applicazione in cui la copia "memorizzata nella cache" è valida.
Se stai incorporando dati con codifica Base64 nelle risposte JSON, allora perdi quella parte importante e tu invii i dati ogni volta. È anche un processo molto complicato da gestire, come hai scoperto.