URL-codering uitgelegd: wat is percent-codering
Elke keer dat u op een link klikt, een formulier verzendt of een webadres intypt, behandelt uw browser URL-codering achter de schermen. Die cryptische reeksen procenttekens en hexadecimale getallen die u in URL's ziet, zijn niet willekeurig; ze vormen een zorgvuldig ontworpen mechanisme dat het internet betrouwbaar laat werken. Begrip van URL-codering is essentieel voor webontwikkelaars, API-ontwerpers en iedereen die met webtechnologieën werkt. Deze gids legt uit wat URL-codering is, waarom het bestaat, hoe het werkt en welke beveiligingsimplicaties u moet kennen.
Wat is URL-codering?
URL-codering, formeel bekend als percent-codering, is een mechanisme dat is gedefinieerd in RFC 3986 en tekens converteert naar een formaat dat veilig kan worden verzonden binnen een Uniform Resource Identifier (URI). De URL-specificatie staat slechts een subset van ASCII-tekens toe om direct in een URL te verschijnen. Elk teken buiten deze toegestane set moet worden gecodeerd als een procentteken ( % ) gevolgd door twee hexadecimale cijfers die de bytewaarde van het teken vertegenwoordigen.
< %3C , omdat de ASCII-code voor < 60 is, wat 3C in hexadecimaal is.
Waarom URL-codering noodzakelijk is
URL's hebben een specifieke syntaxis die bepaalde tekens als scheidingstekens gebruikt. Het vraagteken ? scheidt het pad van de querystring. Het ampersand-teken & scheidt queryparameters. Het gelijkteken = scheidt parameternamen van waarden. De schuine streep / scheidt padsegmenten. Als deze tekens in de verzonden gegevens voorkomen, zouden ze verkeerd worden geïnterpreteerd als URL-structuur in plaats van inhoud.
Bedenk wat er gebeurt wanneer een gebruiker zoekt naar "rock & roll" op een website. Zonder codering zou de URL er zo uitzien: /search?q=rock & roll . De browser zou de & interpreteren als een scheidingsteken voor queryparameters, waardoor de query wordt opgesplitst in twee parameters: q=rock en een tweede parameter met de naam roll zonder waarde. URL-codering lost dit op: /search?q=rock%20%26%20roll .
Hoe percent-codering werkt
Het coderingsproces volgt een eenvoudig algoritme dat is gedefinieerd door de URI-specificatie:
- Identificeer niet-gereserveerde tekens: De tekens A-Z , a-z , 0-9 , - , . , _ en ~ zijn niet-gereserveerd. Ze hoeven nooit te worden gecodeerd en kunnen direct in een URL verschijnen.
- Identificeer gereserveerde tekens: De tekens : , / , ? , # , [ , ] , @ , ! , $ , & , ' , ( , ) , * , + , , , ; en = zijn gereserveerd voor URL-syntaxis. Ze moeten worden gecodeerd wanneer ze als gegevens worden gebruikt in plaats van als scheidingstekens.
- Codeer al het andere: Elk teken dat niet in de niet-gereserveerde of gereserveerde set staat, moet percent-gecodeerd worden. Dit omvat spaties, besturingstekens, non-ASCII-tekens en elk teken buiten het ASCII-bereik.
Het coderingsproces voor non-ASCII-tekens
Non-ASCII-tekens (zoals letters met accenten, CJK-tekens en emoji) vereisen een extra stap. Eerst wordt het teken geconverteerd naar zijn UTF-8-bytereeks. Vervolgens wordt elke byte afzonderlijk percent-gecodeerd. Dit betekent dat een enkel teken meerdere percent-gecodeerde tripletten kan opleveren.
Het Euro-teken ( ) heeft bijvoorbeeld de UTF-8-bytereeks E2 82 AC . Bij URL-codering wordt het %E2%82%AC . Het Chinese teken voor "midden" ( 中 ) heeft de UTF-8-reeks E4 B8 AD , wat %E4%B8%AD oplevert . De emoji 😀 (grijnzend gezicht) heeft een 4-byte UTF-8-reeks, die codeert naar %F0%9F%98%80 .
Veelvoorkomende gecodeerde tekens
De volgende tabel toont de meest voorkomende URL-gecodeerde tekens:
| Teken | Gecodeerd | ASCII-code | Reden |
|---|---|---|---|
| Spatie | %20 | 32 (0x20) | Niet toegestaan in URL's |
| ! | %21 | 33 (0x21) | Gereserveerd (sub-delim) |
| # | %23 | 35 (0x23) | Gereserveerd (fragmentscheidingsteken) |
| $ | %24 | 36 (0x24) | Gereserveerd (sub-delim) |
| & | %26 | 38 (0x26) | Gereserveerd (queryscheidingsteken) |
| ' | %27 | 39 (0x27) | Gereserveerd (sub-delim) |
| ( | %28 | 40 (0x28) | Gereserveerd (sub-delim) |
| ) | %29 | 41 (0x29) | Gereserveerd (sub-delim) |
| + | %2B | 43 (0x2B) | Gereserveerd (spatie in query) |
| , | %2C | 44 (0x2C) | Gereserveerd (sub-delim) |
| / | %2F | 47 (0x2F) | Gereserveerd (padscheidingsteken) |
| : | %3A | 58 (0x3A) | Gereserveerd (schemascheidingsteken) |
| ; | %3B | 59 (0x3B) | Gereserveerd (parameterscheidingsteken) |
| = | %3D | 61 (0x3D) | Gereserveerd (waardescheidingsteken) |
| ? | %3F | 63 (0x3F) | Gereserveerd (queryscheidingsteken) |
| @ | %40 | 64 (0x40) | Gereserveerd (authorityscheidingsteken) |
| [ | %5B | 91 (0x5B) | Gereserveerd (IPv6-letterlijke) |
| ] | %5D | 93 (0x5D) | Gereserveerd (IPv6-letterlijke) |
URL-codering versus HTML-codering
URL-codering en HTML-entiteitscodering worden vaak verward, maar ze dienen volledig verschillende doeleinden en werken in verschillende contexten.
URL-codering
URL-codering converteert tekens naar %XX-formaat voor veilige verzending binnen een URL. Het valt onder RFC 3986 en wordt toegepast op URL-componenten zoals het pad, de querystring en het fragment.
HTML-codering
< en > voor veilige weergave binnen een HTML-document. Het voorkomt dat de browser inhoud interpreteert als HTML-markup. HTML-codering valt onder de HTML-specificatie.
Belangrijkste verschillen
| Aspect | URL-codering | HTML-codering |
|---|---|---|
| Context | URL's en URI's | HTML-documenten |
| Formaat | %XX (procent + hex) | of NNN; |
| < | %3C | < |
| Voorbeeld voor & | %26 | Voorbeeld voor " |
| %22 | " | Doel |
| Veilige URL-transmissie | HTML-injectie voorkomen | Specificatie |
| RFC 3986 | HTML Living Standard | HTML Living Standard |
(HTML-gecodeerd ampersand). Beide zijn geldig, maar URL-codering van het ampersand is de meer correcte benadering omdat het de beoogde betekenis van de gegevens behoudt.
URL-codering in verschillende programmeertalen
Elke grote programmeertaal biedt ingebouwde functies voor URL-codering en -decodering. Het exacte gedrag verschilt echter, en het begrijpen van de verschillen is cruciaal om bugs te voorkomen.
JavaScript
JavaScript biedt drie coderingsfuncties, elk met verschillend gedrag:
// encodeURI - encodes a complete URL
// Preserves: :, /, ?, #, &, =, +, @, ;, ,, !, ~, *, ', (, )
const url = encodeURI("https://example.com/search?q=hello world");
// Result: "https://example.com/search?q=hello%20world"
// encodeURIComponent - encodes a URL component
// Encodes ALL special characters including URL delimiters
const param = encodeURIComponent("price=100&discount=20");
// Result: "price%3D100%26discount%3D20"
// Never use escape() - it is deprecated
// It does not handle Unicode correctlyHet kritieke verschil is dat encodeURI URL-structuurtekens behoudt, terwijl encodeURIComponent alles codeert. Gebruik encodeURI wanneer u een volledige URL hebt en encodeURIComponent wanneer u een enkele parameterwaarde codeert.
Python
from urllib.parse import quote, quote_plus, urlencode
# quote - standard URL encoding (spaces as %20)
encoded = quote("hello world&more")
# Result: "hello%20world%26more"
# quote_plus - spaces become + instead of %20
encoded_plus = quote_plus("hello world")
# Result: "hello+world"
# urlencode - encodes a dictionary as a query string
params = {"q": "hello world", "lang": "en"}
query = urlencode(params)
# Result: "q=hello+world&lang=en"PHP
// urlencode - spaces become +
$encoded = urlencode("hello world&more");
// Result: "hello+world%26more"
// rawurlencode - RFC 3986 compliant (spaces as %20)
$raw = rawurlencode("hello world&more");
// Result: "hello%20world%26more"Het spatieteken: %20 versus +
Het spatieteken heeft twee veelvoorkomende coderingen, en het begrijpen van wanneer u welke moet gebruiken is belangrijk:
- %20: De standaard percent-codering gedefinieerd door RFC 3986. Dit is de juiste codering voor spaties in het padcomponent van een URL en is altijd veilig.
- + (plusteken): Gedefinieerd door het mediatype application/x-www-form-urlencoded, dat wordt gebruikt voor het coderen van formuliergegevens in querystrings. In deze codering worden spaties vervangen door plustekens, en plustekens zelf worden gecodeerd als %2B .
Het onderscheid is belangrijk omdat het decoderen van + als een spatie alleen correct is in de context van application/x-www-form-urlencoded-gegevens. In het URL-padcomponent is + een letterlijk plusteken, geen spatie. De meeste server-side frameworks behandelen dit correct voor querystrings, maar het kan subtiele bugs veroorzaken bij het coderen van paden of het werken met aangepaste URL-schema's.
Beveiligingsimplicaties
URL-codering heeft aanzienlijke beveiligingsimplicaties die elke webontwikkelaar moet begrijpen.
Dubbele coderingsaanvallen
Dubbele codering treedt op wanneer gegevens meer dan eens worden URL-gecodeerd. Een aanvaller zou %2527 kunnen indienen, wat bij de eerste decodeeringspassage %27 oplevert en bij de tweede passage een enkel aanhalingsteken ' . Als een beveiligingsfilter alleen de eerste decodering controleert, mist het het kwaadaardige teken. Dit kan invoervalidatie, cross-site scripting (XSS)-filters en SQL-injectiebescherming omzeilen.