zhihu wu

You are debugging a broken API call. The URL looks fine in your browser, but the server returns 400. You stare at the query string: ?q=hello world&filter=active. There is your problem — that space.

URL encoding is one of those things every developer encounters but few fully understand. Let us fix that.

The Two JavaScript Functions (and Why Both Exist)

encodeURI() is for entire URLs. It preserves characters that have structural meaning: :, /, ?, &, #. Use it when you have a complete URL and just need to make it safe.

encodeURIComponent() is for individual parameter values. It encodes everything except A-Z a-z 0-9 - _ . ! ~ * ' ( ). The & in your filter value? Encoded. The = in your base64 token? Encoded.

encodeURI("https://example.com/search?q=hello world")
// → "https://example.com/search?q=hello%20world"

encodeURIComponent("hello world")
// → "hello%20world"

Enter fullscreen mode Exit fullscreen mode

The rule: encodeURI() for the whole URL, encodeURIComponent() for each parameter value. Mix them up and you either break the URL structure or leave dangerous characters unencoded.

The Double-Encoding Trap

If you encode a string that is already encoded, the % signs get re-encoded to %25. hello%20world becomes hello%2520world. The server decodes once and gets hello%20world — still encoded. A second decode gives you the original, but most servers only decode once.

Spot double-encoding by looking for %25 in your output. If you see it, decode first, then re-encode.

%20 vs + for Spaces

In query strings, HTML forms use + for spaces (application/x-www-form-urlencoded). In path segments, use %20 (RFC 3986). encodeURIComponent() always outputs %20, which is safe everywhere. If your server expects +, use %20 anyway — most modern frameworks handle both.

The Quick Fix

Next time a URL misbehaves, paste it into a decoder, inspect what is actually being sent, and fix the encoding at the source. A free tool like CodeToolbox URL Encoder does this in your browser — no server uploads, instant results.