DevToolBoxฟรี
บล็อก

URL Encoding อักขระพิเศษ: ตารางอ้างอิงฉบับสมบูรณ์

6 นาทีในการอ่านโดย DevToolBox

URL encoding (also called percent encoding) converts special characters into a format that can be safely transmitted in a URL. Every developer encounters URL encoding issues at some point — broken links, garbled parameters, or API errors caused by unencoded characters. This complete URL encoding reference gives you the definitive table of all special characters and their encoded forms, plus practical examples in every major programming language.

Encode or decode any URL instantly with our URL Encoder/Decoder tool →

What Is URL Encoding (Percent Encoding)?

URL encoding replaces unsafe or reserved characters with a % sign followed by two hexadecimal digits representing the character's ASCII/UTF-8 byte value. For example, a space becomes %20, and an ampersand becomes %26.

This mechanism is defined in RFC 3986 (Uniform Resource Identifier: Generic Syntax). URLs can only contain a limited set of characters from the US-ASCII character set. Any character outside this set — or any reserved character used outside its special meaning — must be percent-encoded.

The general format is: %XX where XX is the hexadecimal value of the byte. For multi-byte UTF-8 characters (like Chinese or emoji), each byte is encoded separately. For example, the Chinese character "中" (U+4E2D) encodes to %E4%B8%AD (three bytes in UTF-8).

// URL encoding example
Original:  https://example.com/search?q=hello world&lang=en
Encoded:   https://example.com/search?q=hello%20world&lang=en

// The space in "hello world" becomes %20
// The & and = remain unencoded (they are structural)

Complete URL Encoding Reference Table

Below is a comprehensive table of all commonly encountered special characters and their percent-encoded forms. Bookmark this page for quick reference.

CharacterEncoded FormASCII CodeDescription
(space)%2032Space (also + in form data)
!%2133Exclamation mark
"%2234Double quote
#%2335Hash / Fragment identifier
$%2436Dollar sign
%%2537Percent sign (the escape character itself)
&%2638Ampersand / Parameter separator
'%2739Single quote (apostrophe)
(%2840Left parenthesis
)%2941Right parenthesis
*%2A42Asterisk
+%2B43Plus sign (space in form data)
,%2C44Comma
/%2F47Forward slash / Path separator
:%3A58Colon (scheme separator)
;%3B59Semicolon
<%3C60Less than
=%3D61Equals sign (key-value separator)
>%3E62Greater than
?%3F63Question mark (query string start)
@%4064At sign (email / userinfo separator)
[%5B91Left square bracket
\%5C92Backslash
]%5D93Right square bracket
^%5E94Caret
`%6096Backtick (grave accent)
{%7B123Left curly brace
|%7C124Pipe (vertical bar)
}%7D125Right curly brace
~%7E126Tilde (unreserved in RFC 3986)
\n%0A10Line feed (newline)
\r%0D13Carriage return
\t%099Horizontal tab

Reserved vs Unreserved Characters (RFC 3986)

RFC 3986 defines two categories of characters that determine when encoding is necessary:

Reserved Characters

These characters have special meaning in URLs. If you want to use them literally (not for their special purpose), you must percent-encode them.

: / ? # [ ] @ ! $ & ' ( ) * + , ; =

// Reserved characters in RFC 3986
gen-delims  = : / ? # [ ] @
sub-delims  = ! $ & ' ( ) * + , ; =

// Example: & is reserved (parameter separator)
// To use & literally in a value, encode it:
?search=Tom%26Jerry    // searching for "Tom&Jerry"
?search=Tom&Jerry      // WRONG: "Jerry" becomes a separate param

Unreserved Characters

These characters can be used in a URL without encoding. They have no special meaning:

Letters: A-Z, a-z   Digits: 0-9   Special: - _ . ~

// Unreserved characters (RFC 3986) — never need encoding
ALPHA  = A-Z / a-z
DIGIT  = 0-9
other  = - . _ ~

// These are always safe in any part of a URL:
https://example.com/my-file_name.v2~backup

Everything else — including spaces, non-ASCII characters, and control characters — must always be percent-encoded.

encodeURI vs encodeURIComponent in JavaScript

JavaScript provides two built-in functions for URL encoding, and using the wrong one is one of the most common mistakes:

encodeURI()

Encodes a complete URI. It does NOT encode characters that have special meaning in a URL: : / ? # [ ] @ ! $ & ' ( ) * + , ; =

// encodeURI() — for complete URLs
const url = 'https://example.com/path name/file?q=hello world';
encodeURI(url);
// → "https://example.com/path%20name/file?q=hello%20world"
// Note: :, /, ?, = are NOT encoded (URL structure preserved)

encodeURIComponent()

Encodes a URI component (such as a query parameter value). It DOES encode reserved characters like & = + / — which is exactly what you want for parameter values.

// encodeURIComponent() — for parameter values
const query = 'price=100&currency=USD';
encodeURIComponent(query);
// → "price%3D100%26currency%3DUSD"
// Note: = and & ARE encoded (they're data, not structure)

// Correct usage: build URL piece by piece
const base = 'https://api.example.com/search';
const param = 'Tom & Jerry: The Movie';
const fullUrl = base + '?q=' + encodeURIComponent(param);
// → "https://api.example.com/search?q=Tom%20%26%20Jerry%3A%20The%20Movie"

Rule of thumb: Use encodeURIComponent() for query parameter values and path segments. Use encodeURI() only when encoding an entire URL where you want to preserve the structure.

// Side-by-side comparison
const text = 'hello world & goodbye=fun';

encodeURI(text);
// → "hello%20world%20&%20goodbye=fun"
//    & and = are NOT encoded

encodeURIComponent(text);
// → "hello%20world%20%26%20goodbye%3Dfun"
//    & and = ARE encoded

// decodeURI() and decodeURIComponent() reverse the process
decodeURIComponent('%E4%B8%AD%E6%96%87'); // → "中文"

URL Encoding in Different Programming Languages

Python

# Python 3 — urllib.parse
from urllib.parse import quote, quote_plus, unquote, urlencode

# Encode a path segment (spaces → %20)
quote('hello world/file name')
# → 'hello%20world/file%20name'   (/ is safe by default)

# Encode a path segment including /
quote('hello world/file name', safe='')
# → 'hello%20world%2Ffile%20name'

# Encode a query parameter value (spaces → +)
quote_plus('hello world&foo=bar')
# → 'hello+world%26foo%3Dbar'

# Build query string from dict
urlencode({'q': 'Tom & Jerry', 'page': '1'})
# → 'q=Tom+%26+Jerry&page=1'

# Decode
unquote('%E4%B8%AD%E6%96%87')  # → '中文'

Java

// Java — URLEncoder / URI
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

// Encode a query parameter value (spaces → +)
String encoded = URLEncoder.encode(
    "hello world&foo=bar", StandardCharsets.UTF_8
);
// → "hello+world%26foo%3Dbar"

// Decode
String decoded = URLDecoder.decode(
    "hello+world%26foo%3Dbar", StandardCharsets.UTF_8
);
// → "hello world&foo=bar"

// For path segments, use URI class
import java.net.URI;
URI uri = new URI("https", "example.com", "/path with spaces", "q=hello world", null);
// → https://example.com/path%20with%20spaces?q=hello%20world

Go

// Go — net/url package
package main

import (
    "fmt"
    "net/url"
)

func main() {
    // Encode a query parameter value
    encoded := url.QueryEscape("hello world&foo=bar")
    // → "hello+world%26foo%3Dbar"

    // Encode a path segment
    pathEncoded := url.PathEscape("hello world/file")
    // → "hello%20world%2Ffile"

    // Build a complete URL safely
    u := &url.URL{
        Scheme: "https",
        Host:   "example.com",
        Path:   "/search",
    }
    q := u.Query()
    q.Set("q", "Tom & Jerry")
    q.Set("lang", "en")
    u.RawQuery = q.Encode()
    fmt.Println(u.String())
    // → "https://example.com/search?lang=en&q=Tom+%26+Jerry"
}

PHP

<?php
// PHP — urlencode / rawurlencode

// Query parameter encoding (spaces → +)
echo urlencode('hello world&foo=bar');
// → "hello+world%26foo%3Dbar"

// Path segment encoding (spaces → %20, RFC 3986)
echo rawurlencode('hello world&foo=bar');
// → "hello%20world%26foo%3Dbar"

// Build query string from array
echo http_build_query([
    'q' => 'Tom & Jerry',
    'page' => 1
]);
// → "q=Tom+%26+Jerry&page=1"

// Decode
echo urldecode('hello+world%26foo%3Dbar');
// → "hello world&foo=bar"

echo rawurldecode('hello%20world%26foo%3Dbar');
// → "hello world&foo=bar"
?>

C#

// C# — Uri.EscapeDataString / HttpUtility
using System;
using System.Web;

// Encode a URI component (RFC 3986)
string encoded = Uri.EscapeDataString("hello world&foo=bar");
// → "hello%20world%26foo%3Dbar"

// Encode for query string (spaces → +)
string queryEncoded = HttpUtility.UrlEncode("hello world&foo=bar");
// → "hello+world%26foo%3Dbar"

// Decode
string decoded = Uri.UnescapeDataString("hello%20world%26foo%3Dbar");
// → "hello world&foo=bar"

// Build query string
var query = HttpUtility.ParseQueryString(string.Empty);
query["q"] = "Tom & Jerry";
query["page"] = "1";
string queryString = query.ToString();
// → "q=Tom+%26+Jerry&page=1"

Ruby

# Ruby — URI / CGI
require 'uri'
require 'cgi'

# Encode a component (spaces → %20)
URI.encode_www_form_component('hello world&foo=bar')
# → "hello+world%26foo%3Dbar"

# Encode for path (spaces → %20)
URI::DEFAULT_PARSER.escape('hello world')
# → "hello%20world"

# Build query string
URI.encode_www_form('q' => 'Tom & Jerry', 'page' => '1')
# → "q=Tom+%26+Jerry&page=1"

# Decode
CGI.unescape('hello%20world%26foo%3Dbar')
# → "hello world&foo=bar"

Common URL Encoding Mistakes

1. Double Encoding

Double encoding happens when you encode an already-encoded string. For example, %20 becomes %2520 (the % gets encoded to %25). This is one of the most common and hardest-to-debug URL issues.

// Double encoding example
const value = 'hello world';

// First encoding (correct)
const encoded = encodeURIComponent(value);
// → "hello%20world"

// Accidentally encoding again (BUG!)
const doubleEncoded = encodeURIComponent(encoded);
// → "hello%2520world"
//   %20 → %25 (the %) + 20 → %2520

// The server receives "hello%20world" instead of "hello world"
// Fix: only encode once, at the point where you build the URL

2. Encoding the Entire URL

Never pass an entire URL to encodeURIComponent(). It will encode the ://, /, ?, and = characters, breaking the URL structure. Only encode individual parameter values.

// WRONG: encoding the entire URL
const url = 'https://example.com/api?q=hello world';
encodeURIComponent(url);
// → "https%3A%2F%2Fexample.com%2Fapi%3Fq%3Dhello%20world"
// Completely broken URL!

// CORRECT: only encode the parameter value
const base = 'https://example.com/api';
const query = 'hello world';
const correctUrl = base + '?q=' + encodeURIComponent(query);
// → "https://example.com/api?q=hello%20world"

3. Forgetting + vs %20 for Spaces

In the application/x-www-form-urlencoded format (HTML forms), spaces are encoded as +. In standard percent encoding (RFC 3986), spaces are %20. Most server-side frameworks handle both, but APIs may be strict. When in doubt, use %20.

// + vs %20 for spaces
// Form data (application/x-www-form-urlencoded):
// "hello world" → "hello+world"

// RFC 3986 (URI standard):
// "hello world" → "hello%20world"

// In JavaScript:
encodeURIComponent('hello world');  // → "hello%20world"
// To get + for form data, replace after:
encodeURIComponent('hello world').replace(/%20/g, '+');
// → "hello+world"

// URLSearchParams automatically uses + for spaces:
new URLSearchParams({ q: 'hello world' }).toString();
// → "q=hello+world"

4. Not Encoding Non-ASCII Characters

Characters like café, ü, or CJK characters must be UTF-8 encoded first, then each byte is percent-encoded. Forgetting this causes mojibake (garbled text) in URLs.

// Non-ASCII characters must be UTF-8 encoded first
encodeURIComponent('café');
// → "caf%C3%A9"   (é = 2 UTF-8 bytes: C3 A9)

encodeURIComponent('中文');
// → "%E4%B8%AD%E6%96%87"  (中 = 3 bytes, 文 = 3 bytes)

encodeURIComponent('🚀');
// → "%F0%9F%9A%80"   (rocket emoji = 4 UTF-8 bytes)

5. Encoding Hash Fragments on the Server

The fragment (#section) is never sent to the server — it is client-side only. Encoding or processing it server-side is pointless.

6. Using Deprecated escape() in JavaScript

The escape() function is deprecated and does not handle UTF-8 properly. Always use encodeURI() or encodeURIComponent() instead.

// DEPRECATED — do NOT use
escape('hello world');   // → "hello%20world" (works for ASCII)
escape('café');          // → "caf%E9" (WRONG! not UTF-8)

// CORRECT alternatives
encodeURIComponent('café');  // → "caf%C3%A9" (correct UTF-8)

When to URL Encode: Query Params, Path Segments, Fragment

Different parts of a URL have different encoding rules:

// URL anatomy and encoding zones
https://user:pass@example.com:8080/path/to/page?key=value&k2=v2#section
|____| |_______| |__________| |__||____________||________________||______|
scheme  userinfo    host      port    path         query string   fragment

// Each part has different encoding rules:

Query Parameters

Always encode parameter keys and values. This is the most common place where encoding is needed.

// Query parameters: ALWAYS encode keys and values
const params = new URLSearchParams();
params.set('search', 'C++ programming');    // auto-encodes
params.set('filter', 'price>100&sale=true'); // auto-encodes
params.toString();
// → "search=C%2B%2B+programming&filter=price%3E100%26sale%3Dtrue"

// Or manually:
'?q=' + encodeURIComponent('price > $100 & discount = 20%')
// → "?q=price%20%3E%20%24100%20%26%20discount%20%3D%2020%25"

Path Segments

Encode each path segment individually. Forward slashes (<code>/</code>) that are part of the URL structure should NOT be encoded, but slashes within a segment value must be.

// Path segments: encode each segment individually
const fileName = 'my report (final).pdf';
const path = '/files/' + encodeURIComponent(fileName);
// → "/files/my%20report%20(final).pdf"

// DO NOT encode the structural slashes:
// WRONG: encodeURIComponent('/files/my report.pdf')
// → "%2Ffiles%2Fmy%20report.pdf" (broken path)

Fragment Identifier

The fragment (after <code>#</code>) follows the same encoding rules as query strings. Note that fragments are never sent to the server.

// Fragment: encode like query string values
const section = 'Q&A Section';
const url = '/page#' + encodeURIComponent(section);
// → "/page#Q%26A%20Section"

// Remember: browsers never send fragments to the server
// window.location.hash gives you the raw fragment

Domain Name (Hostname)

Domain names use Punycode (not percent encoding) for internationalized domain names (IDN). For example, muenchen.de with an umlaut becomes xn--mnchen-3ya.de.

// International Domain Names use Punycode, NOT percent encoding
// münchen.de → xn--mnchen-3ya.de
// 中文.com    → xn--fiq228c.com
// 日本語.jp   → xn--wgv71a309e.jp

// In JavaScript:
const url = new URL('https://münchen.de/path');
url.hostname;  // → "xn--mnchen-3ya.de" (auto-converted)

Frequently Asked Questions

What is the difference between %20 and + for spaces?

Both represent a space, but they come from different standards. %20 is defined by RFC 3986 (URI standard) and is used in path segments and modern APIs. + is defined by the application/x-www-form-urlencoded format (HTML forms). In query strings, most servers accept both. For maximum compatibility, use %20.

Should I encode forward slashes (/) in URL paths?

Only if the slash is part of a data value, not a path separator. For example, if a filename contains a slash, it must be encoded as %2F in the path segment. The structural slashes that separate path segments should never be encoded.

How do I encode Unicode characters (e.g., Chinese, Arabic) in URLs?

First convert the character to its UTF-8 byte sequence, then percent-encode each byte. For example, "café" → UTF-8 bytes 63 61 66 C3 A9 → the é becomes %C3%A9. Modern programming languages handle this automatically with their URL encoding functions.

Is URL encoding case-sensitive?

The hexadecimal digits in percent encoding are case-insensitive (%2f and %2F are equivalent). However, RFC 3986 recommends using uppercase letters (%2F) for consistency and normalization.

Do I need to encode the entire URL or just parts of it?

Never encode an entire URL at once. Encode only the individual components — query parameter values, path segments containing special characters, and fragment identifiers. The structural characters (://, /, ?, =, &) must remain unencoded to preserve the URL structure.

URL encoding is a fundamental skill for web development. Keep this reference table handy for quick lookups, and use our tool to encode and decode URLs in real time.

Encode & decode any URL with our URL Encoder/Decoder →

𝕏 Twitterin LinkedIn
บทความนี้มีประโยชน์ไหม?

อัปเดตข่าวสาร

รับเคล็ดลับการพัฒนาและเครื่องมือใหม่ทุกสัปดาห์

ไม่มีสแปม ยกเลิกได้ตลอดเวลา

ลองเครื่องมือที่เกี่ยวข้อง

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

บทความที่เกี่ยวข้อง

REST API Best Practices: คู่มือฉบับสมบูรณ์ 2026

เรียนรู้แนวทางปฏิบัติที่ดีที่สุดในการออกแบบ REST API: การตั้งชื่อ, จัดการ error, authentication และความปลอดภัย

URL Encode & Decode: คู่มือ Percent-Encoding ฉบับสมบูรณ์

ตัวเข้ารหัสและถอดรหัส URL ฟรี เรียนรู้ percent-encoding พร้อมตัวอย่างใน JavaScript, Python, Bash และ PHP