Comment puis-je accéder aux fichiers image dans MongoDB et les envoyer au client à l'aide d'Express.js

Aug 18 2020

J'ai stocké des fichiers image dans MongoDB en utilisant la mangouste. Les images sont soumises à partir d'un formulaire HTML, puis envoyées à MongoDB via une requête POST express. Ensuite, je souhaite accéder à ces fichiers image dans MongoDB via une requête GET, puis les envoyer côté client. Le code pour cela ressemble à ceci:

app.get("/showallimages", (req, res) => {

    Image.find({}).exec((error, records) => { // Image is the database schema model. 

        var img1 = Buffer.from(records[0].img.data, "base64"); // First image coming from MongoDB.
        var img2 = Buffer.from(records[1].img.data, "base64"); // Second image coming from MongoDB.
        var images = [img1, img2];

        res.writeHead(200, {
            "Content-Type": "image/png",
        })

        var i = 0;
        for (i; i <= images.length; i++) {
            res.end(images[i]); // I am expecting this to send both images to the client side, but instead I am only getting the first image to be displayed. 
        }

    })

})

Si je console.log «images», j'obtiens les données binaires des deux fichiers:

console.log(images); 

  <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 02 00 00 64 00 64 00 00 ff ec 00 11 44 75 63 
6b 79 00 01 00 04 00 00 00 22 00 00 ff ee 00 0e 41 64 6f 62 65 00 64 ... 8728 more bytes>,
  <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 05 39 00 00 03 84 08 06 00 
00 00 6a f3 35 f1 00 00 00 01 73 52 47 42 00 ae ce 1c e9 00 00 00 f2 ... 397757 more bytes>

Je m'attends à ce que cela envoie les deux images du côté client, mais à la place, je ne reçois que la première image à afficher.

Toute explication sur la façon dont je peux envoyer plus d'un fichier dans ce processus est appréciée. Dites-moi également si je choisis la bonne façon d’y parvenir.

Merci!

Réponses

1 Victor_Maciel Aug 20 2020 at 19:16

Votre code a une erreur de logique. lorsque res.end () est appelé, express termine le processus de réponse dans la première image, votre boucle n'atteint pas l'itération suivante. De plus, vous ne pouvez pas avoir plusieurs réponses pour une seule demande. Mais vous pouvez envoyer le tableau Buffer avec une représentation JSON en utilisant res.json(images).

Dans le client , pour afficher les images reçues comme tampons du serveur: vous devez les convertir au format d'origine en procédant comme suit:

// server response
const images = response.map(buffer => {
  const rawBuffer = buffer.toString("base64");
  const imageSrc = "data:image/png;base64," + rawBuffer;
  const image = document.createElemment("img");
  image.src = imageSrc;
  return image;
})

/* 
In this method you can control how you will show the images in the client 
(to test, just append to any div)
*/

Ou, si vous souhaitez simplement afficher les images sans aucune manipulation, essayez ceci:

app.get("/showallimages", (req, res) => {

    Image.find({}).exec((error, records) => { // Image is the database schema model. 

        var img1 = Buffer.from(records[0].img.data, "base64"); // First image coming from MongoDB.
        var img2 = Buffer.from(records[1].img.data, "base64"); // Second image coming from MongoDB.
        var images = [img1, img2];

        const formatedImages = images.map(buffer => {
          return `<img src="data:image/png;base64,${buffer.toString("base64")}"/>`
        }).join("")
        
        res.send(formatedImages)

    })

})