WebOntwikkeling 2024
DigitAP
  • Introductie
  • Tooling
    • Devcontainers
    • Git
    • Terminal en bash
  • NodeJS + TypeScript
    • Wat is NodeJS?
    • Waarom TypeScript?
    • Nieuw project
    • Input lezen
    • Type Systeem
      • Basic types
      • Arrays
      • Interfaces
      • Functions
    • Exceptions
    • Modules
    • Asynchroon Programmeren
      • Promises
      • Async/Await
      • Fetch
      • Extra voorbeelden
  • Express.js
    • Wat is een backend framework?
    • Basis
    • Nodemon
    • Statische Bestanden
    • EJS
    • Request
      • GET Request
      • POST Request
      • Multi-part form data
    • Response
    • Router
    • Middleware
    • Deployment
  • MongoDB
    • Wat is MongoDB?
    • MongoDB driver
    • Insert
    • Find
    • Limit & Sort
    • Query Operators
    • Update
    • Delete
    • Text Search
    • Gebruik in Express.js
      • CRUD
  • Security & Testing
    • Environment Variables
    • Cookies
    • Hashing & Encryptie
    • Sessions
      • Session Based Login
    • JWT Tokens
      • JWT NPM package
      • Tokens veilig opslaan
      • Token Based Login
    • Testing
  • Labos
    • 1. Tooling
    • 2. Basis
      • Hello Name
      • BMI Calculator
      • BMI Calculator Multi
      • Interest Calculator
      • Uren en Minuten
      • Wisselgeld
      • Name from Email
      • Text Box
    • 3. Arrays
      • Som van getallen
      • Puntenboek
      • Rot13
      • Pokemon Team
      • Todo List String
      • Tick Tac Toe
    • 4. Interfaces & functies
      • Interfaces
        • Recepten
        • Movies Objects
        • Todo List Objects
      • Functies
        • Math Fun
        • Short Notation
        • Array Sum
        • Movies Functions
        • Filter Numbers
        • At Least Two
    • 5. Async & fetch
      • Fake Fetch
      • Promise All
      • Slow Sum
      • Todo List Fetch
      • Cocktails Promise All
      • Bitcoin API
      • Joke API
      • School API
      • Cocktails API
      • Unix Timestamp API
    • 6. Modules en NPM Packages
      • Math Module
      • Export Interfaces
      • Cowsay Module
      • Cat GPT
      • Rainbow Chalk
    • 7. Express
      • Hello Express
      • DadJoke Express
      • Bitcoin current
    • 8. EJS + Static
      • Hello Express EJS
      • Cat Static
      • Maaltafels
      • Newspaper
    • 9. Get Request
      • Hello Query
      • Math Service
      • Newspaper Route
      • Newspaper Search
      • Steam
    • 10. Post Request
      • Pet Shelter
      • Redirect Form
      • Contact Form
    • 11. Router en Middleware
      • Router Combi
      • Utility Middleware
      • Rate Limiter
    • 12. Herhaling
      • Twitter
      • Word Guess
    • 13. Mongo Basics
      • Guestbook
      • MoviesDB
      • Pokemon Team
    • 14. Mongo Queries
      • Pet Shelter
      • Games DB
    • 15. Mongo + Express
      • Pet Shelter Express
      • Guestbook Express
      • Pokemon Team Express
    • 16. CRUD
      • Users CRUD
      • Pokedex
    • 17. Session & Cookies
      • Shopping Cookie
      • View Counter Cookies
      • View Counter Sessions
    • 18. Session based login
      • Login Express
      • Pokedex Express Sessions
    • 19. Token based login
      • JWT Sign
      • Login Express JWT
    • 20. Testing
      • Math Test
      • String Test
      • Math Express Test
      • Form Express Test
      • Pet Shelter Express Test
    • 21. Herhaling
      • Youtube Favorites
      • Beerster
    • Extra oefeningen
      • DNA Match
      • View Counter
      • Hogwarts Express CRUD
  • Project
    • Voorbereiding (devcontainer + github)
    • Semester 2
      • Milestone 1 - Terminal App
      • Milestone 2 - Express
      • Milestone 3 - MongoDB
      • Milestone 4 - Security
Powered by GitBook
On this page
  • Installatie
  • Basis configuratie
  • Uploaden van 1 bestand
  • Uploaden van meerdere bestanden
  • Forms met meerdere file inputs
  • Meer informatie
Export as PDF
  1. Express.js
  2. Request

Multi-part form data

Soms bestaat een formulier niet enkel uit tekstvelden, maar ook uit bestanden. Denk maar aan een formulier waar je een foto kan uploaden. In dit geval is het niet mogelijk om de data van het formulier te versturen via een GET request. We moeten dan gebruik maken van een POST request. Ook moeten we aangeven dat het formulier een bestand bevat. Dit doen we door de enctype van het formulier aan te passen.

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="avatar" />
    <input type="submit" value="Upload" />
</form>

De enctype van het formulier is nu multipart/form-data. Dit betekent dat de data van het formulier in meerdere delen wordt opgesplitst. We kunnen jammer genoeg niet zomaar de data van het formulier via de req.body variabele ophalen. We moeten hiervoor een aparte module gebruiken. Deze module heet multer. Deze module zorgt ervoor dat we de data van het formulier kunnen ophalen via de req.file (voor 1 file) en req.files (voor meerdere files) variabele.

Installatie

Vooraleer we met multer kunnen werken, moeten we deze eerst installeren. Dit doen we door het volgende commando in de terminal uit te voeren:

npm install multer
npm install --save-dev @types/multer

Basis configuratie

Om multer te kunnen gebruiken, moeten we eerst een multer object aanmaken. Dit object bevat de configuratie van multer. De basisconfiguratie van multer ziet er als volgt uit:

import multer from "multer";

const upload = multer({
    dest: "public/uploads",
});

De dest property van het multer object bevat de map waar de bestanden terecht komen. In dit geval is dit de map uploads. Als we dit niet opgeven, worden de bestanden in het geheugen opgeslagen en worden ze niet opgeslagen op de harde schijf.

By default, Multer zal de bestanden hernoemen zodat er geen conflicten ontstaan. Dus upload je twee keer een bestand met dezelfde naam, dan zal de tweede upload een andere naam krijgen.

Uploaden van 1 bestand

Om een bestand te kunnen uploaden, moeten we de upload.single() functie gebruiken. Deze functie heeft 1 parameter nodig: de naam van het inputveld waar het bestand in staat. In ons voorbeeld is dit het inputveld met de naam file.

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="avatar" />
    <input type="submit" value="Upload" />
</form>
import express from "express";
import ejs from "ejs";
import multer from "multer";
import path from "path";

const app = express();

app.set("view engine", "ejs");
app.use(express.static(path.join(__dirname, "public")));

const upload = multer({
    dest: "public/uploads",
});

app.get("/", (req, res) => {
    res.render("index")
});

app.post("/upload", upload.single("avatar"), (req, res) => {
    let file = req.file as Express.Multer.File;
    if (file) {
        res.type("text/html");
        res.send(`<img src="uploads/${file.filename}"/>`);
    } else {
        res.send("No file uploaded");
    }
});

app.listen(3000, () => {
    console.log("Server started on port 3000");
});

Dit is een voorbeeld van een formulier waarbij we een bestand kunnen uploaden. Als we dit formulier invullen en verzenden, dan wordt het bestand opgeslagen in de map uploads. Omdat we aangegeven hebben dat de map uploads een statische map is, kunnen we het bestand oproepen via de url http://localhost:3000/<bestandsnaam>. In ons voorbeeld is dit bv http://localhost:3000/5f7b9b0e8b9c4a0b8c9d9e0f.

Uploaden van meerdere bestanden

Om meerdere bestanden te kunnen uploaden, moeten we de upload.array() functie gebruiken. Deze functie heeft 2 parameters nodig: de naam van het inputveld waar de bestanden in staan en het aantal bestanden dat geüpload mag worden. In ons voorbeeld is dit het inputveld met de naam photos en mogen er 5 bestanden geüpload worden.

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="photos" multiple />
    <input type="submit" value="Upload" />
</form>

nu kunnen we de bestanden ophalen via de req.files variabele

app.post("/upload", upload.array("photos", 5), (req, res) => {
    let files = req.files as Express.Multer.File[];
    if (files) {
        res.type("text/html");
        res.send(files.map((file) => `<img src="${file.filename}"/>`).join("<br/>"));
    } else {
        res.send("No files uploaded");
    }
});

Forms met meerdere file inputs

Als je een formulier hebt met meerdere file inputs, dan moet je de upload.fields() functie gebruiken. Deze functie heeft 1 parameter nodig: een array met objecten. Elk object bevat de naam van het inputveld en het aantal bestanden dat geüpload mag worden.

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="avatar" />
    <input type="file" name="gallery" multiple />
    <input type="submit" value="Upload" />
</form>
interface FilesDictionary {
    [fieldname: string]: Express.Multer.File[];
}

app.post(
    "/upload",
    upload.fields([
        { name: "avatar", maxCount: 1 },
        { name: "gallery", maxCount: 8 },
    ]),
    (req, res) => {
        let files = req.files as FilesDictionary
        let avatar = files["avatar"][0];

        res.type("text/html");
        res.send(`<h1>Avatar</h1>
                  <img src="/${avatar.filename}"><br/>
                  <h1>Photos</h1>
                  ${files["gallery"].map((file) => `<img src="/${file.filename}">`).join("")}}`);
    }
);

De types van de req.files variabele zijn niet zo duidelijk. We kunnen de types van de req.files variabele dus beter zelf definiëren. Dit doen we door een interface aan te maken met de naam FilesDictionary. Deze interface bevat een index signature. Dit is een manier om een object te definiëren waarbij de keys van het object niet vooraf gekend zijn. In ons geval weten we niet hoeveel bestanden er geüpload worden. Daarom gebruiken we een index signature.

Meer informatie

PreviousPOST RequestNextResponse

Last updated 1 year ago

Voor meer informatie over multer, kan je terecht op de volgende pagina:

http://expressjs.com/en/resources/middleware/multer.html