DevToolBoxZA DARMO
Blog

URL Encode & Decode: Kompletny Przewodnik Percent-Encoding

10 min czytaniaby DevToolBox

URL encoding (also known as percent encoding) is one of the most essential mechanisms in web development. Every time you submit a form, click a link with query parameters, or call a REST API, URL encode and URL decode operations happen behind the scenes. Whether you need a quick URL encoder for a one-off task, want to url encode online without installing anything, or need to understand why encodeURIComponent exists, this comprehensive guide covers everything from the RFC 3986 specification to practical code examples in JavaScript, Python, Bash, PHP, and Java. If you need to quickly urlencode or decode url online, try our free tool.

Try our free online URL Encode/Decode tool instantly.

What Is URL Encoding (Percent Encoding)?

URL encoding, formally defined in RFC 3986, is a mechanism for encoding information in a Uniform Resource Identifier (URI) by replacing unsafe or reserved characters with a percent sign (%) followed by two hexadecimal digits representing the character's byte value. For example, a space character (ASCII 32, hex 20) becomes %20. This process is also called percent encoding because every encoded character starts with the % symbol.

URLs can only contain a limited set of characters from the US-ASCII character set. The url safe characters that do NOT need encoding are: uppercase letters (A-Z), lowercase letters (a-z), digits (0-9), and four special characters: hyphen (-), underscore (_), period (.), and tilde (~). These are called "unreserved characters" in RFC 3986. Every other character, including spaces, non-ASCII characters (like Chinese, Japanese, or emoji), and reserved delimiters, must be percent-encoded when used in contexts where they would otherwise be interpreted as URI delimiters.

Why do URLs need encoding? URLs serve as universal addresses on the web, and they must be unambiguous. Characters like &, =, ?, and # have special structural meanings in URLs: ? separates the path from the query string, & separates query parameters, = separates keys from values, and # marks a fragment. If your data contains these characters (for example, a search query like "cats & dogs"), they must be encoded (cats%20%26%20dogs) so the browser and server can distinguish data from URL structure. Without proper url encode operations, URLs would break or be misinterpreted.

How URL Encoding Works

The URL encode process follows a straightforward algorithm. For each character that needs encoding:

  1. Convert the character to its byte representation using UTF-8 encoding. ASCII characters produce a single byte; non-ASCII characters (like u00e9 or CJK characters) produce 2-4 bytes.
  2. For each byte, write a percent sign (%) followed by the two-digit uppercase hexadecimal value of that byte.
  3. Unreserved characters (A-Z a-z 0-9 - _ . ~) are left as-is without encoding.
  4. Reserved characters (: / ? # [ ] @ ! $ & ' ( ) * + , ; =) are encoded only when they appear in a context where they would be misinterpreted (e.g., inside a query parameter value).

Example: Encoding the string Hello World! Price: $5 produces Hello%20World%21%20Price%3A%20%245. Each space becomes %20, the exclamation mark becomes %21, the colon becomes %3A, and the dollar sign becomes %24.

UTF-8 multi-byte example: The character e with accent (U+00E9) encodes to two UTF-8 bytes 0xC3 0xA9, which become %C3%A9. A Chinese character like zhong (U+4E2D) encodes to three UTF-8 bytes 0xE4 0xB8 0xAD, producing %E4%B8%AD. The URL decoder reverses this process by reading the hex values, reconstructing the bytes, and converting back to UTF-8 characters.

URL Encoding Reference Table

Here is a comprehensive reference table of commonly encoded characters. Bookmark this for quick lookup when you need to <strong>url encode</strong> special characters:

CharacterEncodedDescription
(space)%20Space
!%21Exclamation mark
#%23Hash / Fragment
$%24Dollar sign
%%25Percent sign
&%26Ampersand
'%27Apostrophe
(%28Left parenthesis
)%29Right parenthesis
*%2AAsterisk
+%2BPlus sign
,%2CComma
/%2FForward slash
:%3AColon
;%3BSemicolon
=%3DEquals sign
?%3FQuestion mark
@%40At sign
[%5BLeft bracket
]%5DRight bracket
{%7BLeft brace
}%7DRight brace
|%7CPipe
<%3CLess than
>%3EGreater than
"%22Double quote

Space Encoding: %20 vs + (Plus Sign)

One of the most confusing aspects of URL encoding is how spaces are handled. There are two valid ways to url encode space characters, and which one you should use depends on the context:

%20 (Percent encoding): This is the standard encoding defined by RFC 3986 for use in URIs. When you url encode a space in a URL path, query parameter name, or any generic URI component, use %20. For example: https://example.com/my%20file.html or https://api.example.com/search?q=hello%20world.

+ (Plus sign): This encoding is defined by the application/x-www-form-urlencoded content type specification (used by HTML forms). When an HTML form is submitted with method="GET" or method="POST" with default encoding, spaces in form values are encoded as +. For example: ?q=hello+world. This is a legacy format from HTML 2.0 that persists in web browsers today.

When to use which? If you are building a URL programmatically (API calls, REST endpoints, constructing links), always use %20. If you are encoding data specifically for application/x-www-form-urlencoded format (HTML form submission, URLSearchParams in JavaScript), the + encoding is used automatically. The URL decoder must be aware of the context to correctly interpret + signs: in form data, + means space; in a regular URI, + is a literal plus sign that should NOT be decoded to a space.

// Space encoding comparison

// RFC 3986 (URI standard) — space = %20
"hello world"  →  "hello%20world"
// Used in: URL paths, API endpoints, general URIs

// application/x-www-form-urlencoded — space = +
"hello world"  →  "hello+world"
// Used in: HTML form submissions, URLSearchParams

// JavaScript comparison:
encodeURIComponent("hello world")  // "hello%20world"  (%20)
new URLSearchParams({q: "hello world"}).toString()  // "q=hello+world"  (+)

// Python comparison:
urllib.parse.quote("hello world")      # "hello%20world"  (%20)
urllib.parse.urlencode({"q": "hello world"})  # "q=hello+world"  (+)

// PHP comparison:
rawurlencode("hello world")  // "hello%20world"  (%20)
urlencode("hello world")     // "hello+world"    (+)

URL Encode/Decode Code Examples

JavaScript URL Encode/Decode

JavaScript provides several built-in functions for URL encoding. The most important distinction is between encodeURIComponent and encodeURI. Understanding when to use each is critical for correct url encode operations:

// ===== encodeURIComponent vs encodeURI =====

// encodeURIComponent — encodes EVERYTHING except: A-Z a-z 0-9 - _ . ~
// Use for: individual query parameter values, path segments
encodeURIComponent("hello world & goodbye");
// "hello%20world%20%26%20goodbye"

encodeURIComponent("price=100&category=books");
// "price%3D100%26category%3Dbooks"

// encodeURI — preserves URL structure characters: : / ? # & = @ + $
// Use for: encoding a complete URL
encodeURI("https://example.com/search?q=hello world&lang=en");
// "https://example.com/search?q=hello%20world&lang=en"

// WARNING: Do NOT use encodeURIComponent on full URLs!
encodeURIComponent("https://example.com/path");
// "https%3A%2F%2Fexample.com%2Fpath"  ← BROKEN URL!

// ===== Decoding =====
decodeURIComponent("hello%20world%20%26%20goodbye");
// "hello world & goodbye"

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

// ===== URLSearchParams (handles form encoding automatically) =====
const params = new URLSearchParams({
  query: "cats & dogs",
  page: "1",
  filter: "price > 50"
});
params.toString();
// "query=cats+%26+dogs&page=1&filter=price+%3E+50"
// Note: spaces become + (form encoding), & in values becomes %26

// Parse query string
const parsed = new URLSearchParams("?q=hello+world&lang=en");
parsed.get("q");  // "hello world" (+ decoded to space)
parsed.get("lang");  // "en"

// ===== Building URLs with the URL API =====
const url = new URL("https://api.example.com/search");
url.searchParams.set("q", "hello world & more");
url.searchParams.set("limit", "10");
url.toString();
// "https://api.example.com/search?q=hello+world+%26+more&limit=10"

Python URL Encode/Decode

Python's urllib.parse module provides comprehensive URL encode and URL decode functions. The requests library handles encoding automatically for API calls:

import urllib.parse

# ===== quote / unquote (RFC 3986 percent-encoding) =====

# Encode a string (spaces become %20)
urllib.parse.quote("hello world & goodbye")
# "hello%20world%20%26%20goodbye"

# By default, / is NOT encoded (safe="/")
urllib.parse.quote("/path/to/file name.txt")
# "/path/to/file%20name.txt"

# Encode everything including /
urllib.parse.quote("/path/to/file", safe="")
# "%2Fpath%2Fto%2Ffile"

# Decode
urllib.parse.unquote("hello%20world%20%26%20goodbye")
# "hello world & goodbye"

# ===== urlencode (for query strings, uses + for spaces) =====
params = {"q": "cats & dogs", "page": 1, "filter": "price > 50"}
urllib.parse.urlencode(params)
# "q=cats+%26+dogs&page=1&filter=price+%3E+50"

# ===== quote_plus (form encoding, spaces become +) =====
urllib.parse.quote_plus("hello world")
# "hello+world"

urllib.parse.unquote_plus("hello+world")
# "hello world"

# ===== With the requests library =====
import requests

# requests handles URL encoding automatically
response = requests.get(
    "https://api.example.com/search",
    params={"q": "hello world", "lang": "en"}
)
# Actual URL: https://api.example.com/search?q=hello+world&lang=en

# For path segments, encode manually
username = "john@example.com"
url = f"https://api.example.com/users/{urllib.parse.quote(username, safe='')}"
# "https://api.example.com/users/john%40example.com"

Bash / curl URL Encode/Decode

When working with curl or shell scripts, you often need to urlencode data for HTTP requests. The --data-urlencode flag is the simplest approach:

# ===== curl --data-urlencode =====

# GET request with URL-encoded query parameter
curl -G "https://api.example.com/search" \
  --data-urlencode "q=hello world & more" \
  --data-urlencode "lang=en"
# Request URL: /search?q=hello%20world%20%26%20more&lang=en

# POST with form-encoded body
curl -X POST "https://api.example.com/submit" \
  --data-urlencode "name=John Doe" \
  --data-urlencode "message=Hello! How are you?"

# ===== Pure Bash URL encoding (using printf) =====
urlencode() {
  local string="${1}"
  local strlen=${#string}
  local encoded=""
  local pos c o
  for (( pos=0 ; pos<strlen ; pos++ )); do
    c=${string:$pos:1}
    case "$c" in
      [-_.~a-zA-Z0-9]) o="${c}" ;;
      *) printf -v o '%%%02X' "'$c" ;;
    esac
    encoded+="${o}"
  done
  echo "${encoded}"
}

urlencode "hello world & goodbye"
# "hello%20world%20%26%20goodbye"

# ===== Using Python one-liner in Bash =====
python3 -c "import urllib.parse; print(urllib.parse.quote('hello world'))"
# "hello%20world"

# ===== Decode URL-encoded strings =====
python3 -c "import urllib.parse; print(urllib.parse.unquote('hello%20world'))"
# "hello world"

PHP URL Encode/Decode

PHP provides two pairs of functions for URL encoding. Understanding the difference between urlencode() and rawurlencode() is essential for correct percent encoding:

<?php
// ===== urlencode / urldecode =====
// Uses + for spaces (application/x-www-form-urlencoded)

echo urlencode("hello world & goodbye");
// "hello+world+%26+goodbye"

echo urldecode("hello+world+%26+goodbye");
// "hello world & goodbye"

// ===== rawurlencode / rawurldecode =====
// Uses %20 for spaces (RFC 3986)

echo rawurlencode("hello world & goodbye");
// "hello%20world%20%26%20goodbye"

echo rawurldecode("hello%20world%20%26%20goodbye");
// "hello world & goodbye"

// ===== When to use which? =====
// urlencode()    → for query string values (form-style)
// rawurlencode() → for URL path segments (RFC 3986)

// Building a URL with encoded path and query
$path = rawurlencode("my file.pdf");
$query = urlencode("search term & more");
$url = "https://example.com/files/{$path}?q={$query}";
// "https://example.com/files/my%20file.pdf?q=search+term+%26+more"

// ===== http_build_query (encode arrays as query strings) =====
$params = [
    "q" => "cats & dogs",
    "page" => 1,
    "tags" => ["php", "url encoding"]
];
echo http_build_query($params);
// "q=cats+%26+dogs&page=1&tags%5B0%5D=php&tags%5B1%5D=url+encoding"
?>

Java URL Encode/Decode

Java's URLEncoder and URLDecoder classes handle URL encode and URL decode operations. Always specify UTF-8 encoding explicitly:

import java.net.URLEncoder;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

// ===== URLEncoder.encode (uses + for spaces) =====

// Always specify UTF-8 charset!
String encoded = URLEncoder.encode(
    "hello world & goodbye", StandardCharsets.UTF_8
);
// "hello+world+%26+goodbye"

// Decode
String decoded = URLDecoder.decode(
    "hello+world+%26+goodbye", StandardCharsets.UTF_8
);
// "hello world & goodbye"

// ===== Convert + to %20 for RFC 3986 compliance =====
String rfc3986 = URLEncoder.encode("hello world", StandardCharsets.UTF_8)
    .replace("+", "%20");
// "hello%20world"

// ===== Java 11+ URI encoding =====
import java.net.URI;

URI uri = URI.create("https://example.com/search");
// For building URLs with encoded parameters:
String query = "q=" + URLEncoder.encode("hello world", StandardCharsets.UTF_8);
URI fullUri = URI.create("https://example.com/search?" + query);
// https://example.com/search?q=hello+world

// ===== Encoding path segments =====
String pathSegment = URLEncoder.encode("my file.pdf", StandardCharsets.UTF_8)
    .replace("+", "%20");
String url = "https://example.com/files/" + pathSegment;
// "https://example.com/files/my%20file.pdf"

Common URL Encoding Mistakes

Even experienced developers make these URL encoding errors. Here are the most common pitfalls to avoid:

Double encoding: This occurs when you encode a string that has already been encoded. For example, hello world becomes hello%20world after the first encoding, then hello%2520world after accidental double encoding (the % itself gets encoded to %25). This is the most common URL encoding bug. To fix it: always encode raw/unencoded values, and never pass already-encoded strings through an encoder again.

// Double encoding example — a common bug!

const value = "hello world";

// Correct: encode once
const correct = encodeURIComponent(value);
// "hello%20world" ✓

// Bug: encode twice
const doubleEncoded = encodeURIComponent(encodeURIComponent(value));
// "hello%2520world" ✗  (%25 is the encoded form of %)

// How to detect double encoding:
// If you see %25 in your URLs, you likely have a double encoding issue
// %2520 = double-encoded space (%25 = %, 20 = space)
// %253A = double-encoded colon (%25 = %, 3A = :)

Encoding the entire URL: A frequent error is running the entire URL through encodeURIComponent(). This will encode the slashes, colons, and other structural characters, breaking the URL. For example, https://example.com/path?q=value becomes https%3A%2F%2Fexample.com%2Fpath%3Fq%3Dvalue, which is completely invalid as a URL. Instead, only encode the individual parameter values, not the entire URL structure. Use encodeURI() if you need to encode a full URL (it preserves structural characters), or use encodeURIComponent() only on individual query parameter values.

// Encoding the entire URL — WRONG!
const url = "https://example.com/path?q=hello world";

// WRONG: breaks URL structure
encodeURIComponent(url);
// "https%3A%2F%2Fexample.com%2Fpath%3Fq%3Dhello%20world"

// CORRECT option 1: use encodeURI for full URLs
encodeURI(url);
// "https://example.com/path?q=hello%20world"

// CORRECT option 2: encode only the value
const base = "https://example.com/path";
const query = encodeURIComponent("hello world");
const fullUrl = base + "?q=" + query;
// "https://example.com/path?q=hello%20world"

Forgetting UTF-8: In some languages (especially Java and older PHP), the default encoding might not be UTF-8. Java's URLEncoder.encode(str, "UTF-8") requires explicit charset specification. Always use UTF-8 for URL encoding, as mandated by RFC 3986 and the WHATWG URL specification. Using Latin-1 or other encodings will produce incorrect percent-encoded sequences for non-ASCII characters.

Not encoding path segments: Developers sometimes forget that URL path segments also need encoding. A file path like /documents/my report.pdf must become /documents/my%20report.pdf. Similarly, path parameters that contain slashes or other reserved characters must be encoded.

Mishandling the + sign: Treating + as a space in all contexts is wrong. In application/x-www-form-urlencoded format, + means space. But in a regular URL path or fragment, + is a literal plus sign. Using the wrong decoder can corrupt data containing actual plus signs.

URL Encoding in APIs and Web Applications

Understanding how to properly url encode data is critical when working with APIs and web applications. Here are the key contexts:

Query parameters: When building API URLs with query parameters, each parameter name and value must be individually encoded. For example, if you are searching for price > 100 & category = "electronics", the URL should be /search?q=price%20%3E%20100%20%26%20category%20%3D%20%22electronics%22. Most HTTP client libraries (axios, fetch, requests) handle this automatically when you pass parameters as objects.

Path parameters: Values embedded in URL paths must also be encoded. A REST API endpoint like /users/{username}/repos needs encoding if the username contains special characters: /users/john%40example.com/repos. Unlike query parameters, path segments should use standard percent encoding and never use + for spaces.

Form data: When sending application/x-www-form-urlencoded data in a POST request body, the encoding rules differ from standard URL encoding. Spaces are encoded as +, and the data is formatted as key1=value1&key2=value2. Most frameworks handle this automatically, but be aware of the difference if you are constructing form-encoded bodies manually.

JSON payloads: When sending JSON in a request body (application/json), you do NOT need to URL-encode the JSON content. URL encoding is only for URL components (path, query string, fragment) and form-encoded bodies. However, if you ever need to pass JSON as a query parameter value, the entire JSON string must be URL-encoded.

// API URL encoding examples

// Query parameters — encode each value individually
const searchTerm = 'price > 100 & category = "electronics"';
const apiUrl = `https://api.example.com/search?q=${encodeURIComponent(searchTerm)}&limit=10`;
// "https://api.example.com/search?q=price%20%3E%20100%20%26%20...&limit=10"

// Path parameters — encode values embedded in paths
const username = "john@example.com";
const profileUrl = `https://api.example.com/users/${encodeURIComponent(username)}/profile`;
// "https://api.example.com/users/john%40example.com/profile"

// Form data (POST) — uses + for spaces
const formBody = new URLSearchParams({
  username: "john doe",
  password: "p@ss w0rd!"
}).toString();
// "username=john+doe&password=p%40ss+w0rd%21"

// JSON as query parameter — encode the entire JSON string
const filters = JSON.stringify({ price: { min: 10, max: 100 } });
const url = `/api/products?filters=${encodeURIComponent(filters)}`;
// "/api/products?filters=%7B%22price%22%3A%7B%22min%22%3A10%2C%22max%22%3A100%7D%7D"

Frequently Asked Questions

What is URL encoding and why is it needed?

URL encoding (percent encoding) is the process of converting characters into a format that can be safely transmitted in a URL. It replaces unsafe characters with a percent sign followed by two hex digits (e.g., space becomes %20). It is needed because URLs can only contain a limited set of ASCII characters. Special characters like &, =, ?, #, and spaces have structural meaning in URLs, so they must be encoded when used as data to prevent misinterpretation by browsers and servers. Non-ASCII characters (Unicode, CJK, emoji) must also be UTF-8 encoded then percent-encoded for inclusion in URLs.

What is the difference between encodeURI and encodeURIComponent?

encodeURI() encodes a complete URI, preserving characters that have special meaning in URLs such as :, /, ?, #, &, and =. Use it when you have a full URL string and want to encode only the unsafe characters while keeping the URL structure intact. encodeURIComponent() encodes everything except unreserved characters (A-Z, a-z, 0-9, -, _, ., ~), including the structural URL characters. Use it when encoding individual query parameter values, path segments, or any data that will be embedded in a URL. Using encodeURIComponent on a full URL will break it by encoding the slashes and colons.

Should I use %20 or + for spaces in URLs?

Use %20 for spaces in URL paths and when building URLs programmatically according to RFC 3986. Use + for spaces only in application/x-www-form-urlencoded content, which is the format used by HTML form submissions. In practice: JavaScript encodeURIComponent() produces %20, while URLSearchParams uses +. Python urllib.parse.quote() produces %20, while urllib.parse.urlencode() produces +. When in doubt, %20 is the safer and more universally correct choice, as it works in all URL contexts.

URL encoding is a fundamental web development skill that every developer encounters daily. From constructing API calls to handling form submissions, understanding how to properly url encode and url decode data prevents bugs, security vulnerabilities, and broken links. Bookmark this guide for quick reference, and use our free online tool for instant encoding and decoding.

URL encode and decode strings instantly with our free online tool.

𝕏 Twitterin LinkedIn
Czy to było pomocne?

Bądź na bieżąco

Otrzymuj cotygodniowe porady i nowe narzędzia.

Bez spamu. Zrezygnuj kiedy chcesz.

Try These Related Tools

%20URL Encoder/Decoder🔗URL Parser%←URL Decoder%%Percent Encoding Tool

Related Articles

Kodowanie URL znaków specjalnych: Kompletna tabela referencji

Kompletna referencja kodowania procentowego URL.

Base64 Encode & Decode: Kompletny Przewodnik z Przykładami Kodu

Darmowy encoder i decoder Base64 online. Naucz się kodowania Base64 z przykładami w JavaScript, Python, Bash i PowerShell.

Przewodnik URL Encoder Decoder Online: Kodowanie Procentowe, RFC 3986 i Najlepsze Praktyki

Kompletny przewodnik kodowania URL (kodowanie procentowe). RFC 3986, encodeURIComponent vs encodeURI, Python urllib.parse, Java URLEncoder, popularne zakodowane znaki, kodowanie formularzy, parametry zapytan API.