URI's en URL's
Een URL (Uniform Resource Locator) is het adres van een bron op het web. Ze zegt niet alleen welke bron je wil, maar ook waar en hoe je ze bereikt. Elk onderdeel van dat adres wordt door een andere partij gebruikt: de browser, DNS, de transportlaag, de server, en soms enkel de pagina zelf.
Anatomie van een URL
scheme://gebruiker@host:poort/pad?query#fragment
Een voorbeeld waarin alles voorkomt:
https://api.voorbeeld.be:8443/v1/gebruikers?rol=admin&pagina=2#resultaten
| Onderdeel | Waarde | Wie gebruikt het | Wat het doet |
|---|---|---|---|
| scheme | https | Browser | Bepaalt het protocol en de standaardpoort |
| host | api.voorbeeld.be | DNS | Wordt vertaald naar een IP-adres |
| poort | 8443 | Transportlaag | Zegt welk programma op die machine antwoordt |
| pad | /v1/gebruikers | Server | Welke bron je vraagt |
| query | rol=admin&pagina=2 | Server | Extra parameters: filteren, sorteren, pagineren |
| fragment | resultaten | Enkel de browser | Naar welk stuk van de pagina gescrold wordt |
Scheme
Het scheme bepaalt welk protocol gebruikt wordt, en daarmee ook de standaardpoort:
| Scheme | Standaardpoort | Waarvoor |
|---|---|---|
http | 80 | Onversleuteld web |
https | 443 | Versleuteld web, zie HTTPS & TLS |
ws / wss | 80 / 443 | WebSockets: een open verbinding in twee richtingen |
ftp | 21 | Bestandsoverdracht (verouderd) |
mailto | – | Opent een mailprogramma in plaats van een verbinding |
Komt de poort overeen met de standaard van het scheme, dan mag je ze weglaten: https://ap.be en https://ap.be:443 zijn identiek. Bij je dev server staat de poort er wél bij, omdat 5173 geen standaard is.
Host
De host is de domeinnaam of het IP-adres van de server. Dit is het enige stuk dat via DNS vertaald wordt naar een adres waar het netwerk mee overweg kan.
https://www.ap.be/onderwijs -> DNS zoekt enkel www.ap.be op
De host komt ook nog eens apart mee in het request, als de Host-header. Dat is nodig omdat één server honderden domeinen kan bedienen. Zie HTTP-headers.
Pad
Het pad identificeert de bron op die server. Soms komt het letterlijk overeen met een bestand op schijf, vaker wordt het door de applicatie geïnterpreteerd:
/over-ons.html -> misschien een echt bestand
/producten/42 -> een applicatie zoekt product 42 op in een databank
/v1/gebruikers -> een API-route, zie JSON & REST
Voor de browser maakt dat verschil niets uit: hij vraagt gewoon dat pad op. Hoe paden in API's een vaste betekenis krijgen, lees je in JSON, REST & clientverzoeken.
Query-parameters
Alles na het vraagteken zijn query-parameters: sleutel-waardeparen, gescheiden door &.
https://voorbeeld.be/producten?categorie=laptops&max_prijs=1000&pagina=2
Ze horen bij het filteren, sorteren en pagineren van een bron, niet bij het uitvoeren van een actie. ?id=42 om een product op te vragen kan, maar ?actie=verwijderen hoort niet: daarvoor bestaan methoden.
Query-parameters gaan mee naar de server en verschijnen dus ook in serverlogs. Zet er nooit wachtwoorden of tokens in.
Speciale tekens: URL-encoding
Een URL mag geen spaties of accenten bevatten. Die worden gecodeerd als % plus de hexadecimale waarde van de byte:
| Teken | Gecodeerd |
|---|---|
| spatie | %20 (in een query soms +) |
é | %C3%A9 |
& | %26 |
/ | %2F |
https://voorbeeld.be/zoek?q=caf%C3%A9%20antwerpen
Dat é twee bytes wordt, komt rechtstreeks uit tekstcodering: UTF-8 slaat dat teken op als C3 A9.
Gebruik de ingebouwde functies in plaats van zelf tekens te vervangen:
encodeURIComponent('café antwerpen') // 'caf%C3%A9%20antwerpen'
curl --get --data-urlencode "q=café antwerpen" https://voorbeeld.be/zoek
Fragment
Het fragment (#resultaten) verwijst naar een plek binnen de pagina. Het wordt nooit naar de server gestuurd: het blijft volledig aan de browserkant.
Dat kan je zelf nakijken. Open de Network tab, ga naar een pagina met een anker, en bekijk het request: in de startlijn staat het pad zonder het fragment. Zie Netwerkverkeer bekijken.
Een URI identificeert een bron. Een URL doet dat én zegt waar en hoe je ze vindt. Elke URL is dus een URI, maar niet omgekeerd. In de praktijk van webontwikkeling gebruik je vrijwel altijd URL's, en worden de termen door elkaar gebruikt.
Absolute en relatieve URL's
In HTML gebruik je zelden een volledige URL. Een relatieve verwijzing wordt door de browser aangevuld met de huidige pagina:
| In je HTML | Op pagina https://voorbeeld.be/blog/artikel wordt dat |
|---|---|
https://cdn.be/logo.png | https://cdn.be/logo.png (absoluut, ongewijzigd) |
/img/logo.png | https://voorbeeld.be/img/logo.png (vanaf de root) |
logo.png | https://voorbeeld.be/blog/logo.png (naast de pagina) |
../logo.png | https://voorbeeld.be/logo.png (één map omhoog) |
De klassieke fout is de derde regel: je verplaatst een pagina naar een andere map en al je afbeeldingen geven plots 404. In de Network tab zie je meteen welk adres de browser er dan van maakte.
Test jezelf
1. Welk deel van `https://voorbeeld.be/producten?id=42#reviews` bereikt de server nooit?
2. Waarom staat er `:5173` in `http://localhost:5173` en niet in `https://ap.be`?
3. Je zoekt naar `caf&bar`. Wat gebeurt er met de `&` in de query?
- Een URL bestaat uit scheme · host · poort · pad · query · fragment.
- Elk onderdeel heeft een eigen afnemer: de host gaat naar DNS, de poort naar de transportlaag, pad en query naar de server, het fragment blijft bij de browser.
- Standaardpoorten (
80voor http,443voor https) mag je weglaten. - Query-parameters dienen om te filteren en te pagineren, niet om acties uit te voeren.
- Speciale tekens worden URL-gecodeerd; gebruik
encodeURIComponent()in plaats van dat zelf te doen.