URL Encodingとは?Percent-Encoding完全ガイド
検索する、special charactersを含むlinkをclickする、web formを送信する。そのたびにURL encodingは裏側で動いています。unsafe charactersをinternet上で安全に送れるformatへ変換します。
目次
URLとは?
URL、つまりUniform Resource Locatorは、internet上のresourceのaddressです。pages、images、API endpoints、files、downloadsにはすべてURLがあります。
URLはbrowserに、resourceがどこにあるか、どのprotocolを使うか、query parametersやfragmentsなどのextra dataをどう適用するかを伝えます。
たとえばhttps://www.example.com/search?q=hello+worldにはscheme、host、path、query stringが含まれます。
URLの構造
完全なURLには複数のcomponentsを含められます。
https://user:pass@www.example.com:443/path/page?key=value&q=test#section
scheme userinfo host port path query fragment| Component | 例 | 説明 |
|---|---|---|
| Scheme | https | resourceへaccessするためのprotocol |
| User info | user:pass | 任意のcredentials。現在はあまり使われません |
| Host | www.example.com | serverのdomain nameまたはIP address |
| Port | 443 | server port。HTTP/HTTPSでは通常implicitです |
| Path | /path/page | server上のspecific resource location |
| Query | key=value&q=test | question mark以降のkey-value data |
| Fragment | #section | serverへ送信されないpage bookmark |
URL Encodingとは?
URL encodingはpercent-encodingとも呼ばれ、URL内でunsafeまたは許可されないcharactersを安全な表現へ変換します。
formatはpercent signの後に2桁のhexadecimal digitsを続けます。spaceはASCII byteがdecimal 32、hex 20なので%20になります。
Percent-encodingはRFC 3986などのURI standardsで定義され、URLがtextを安全に運ぶための中核です。
Before encoding:
https://example.com/search?q=hello world&lang=en
After encoding:
https://example.com/search?q=hello%20world&lang=en
Space becomes %20URL Encodingが必要な理由
URL encodingはいくつかの理由で必要です。
- Reserved charactersには意味がある -
?、&、=、#などはURL partsを区切ります。 - Spacesは直接使えない - URLではspaceを
%20、またはform dataでは+としてencodeする必要があります。 - Non-ASCII textにはbytesが必要 - Thai、Japanese、accented letters、emojiはまずUTF-8 bytesへ変換されます。
- Data integrityが重要 - encodingによりbrowser、proxy、serverがuser dataをURL structureとして誤読するのを防ぎます。
- Securityはcontextに依存する - 正しいencodingはparameter injectionやbroken redirectsの防止に役立ちます。
URL Encodingの仕組み
processは単純です。
- encodingが必要なcharacterを取ります。
- UTF-8 bytesへ変換します。
- 各byteを%と2桁のuppercase hexadecimal digitsで書きます。
ASCII charactersでは、各characterは1 byteです。
Character: space ASCII: 32 Hex: 20 Encoded: %20
Character: ! ASCII: 33 Hex: 21 Encoded: %21
Character: # ASCII: 35 Hex: 23 Encoded: %23
Character: @ ASCII: 64 Hex: 40 Encoded: %40Non-ASCII charactersでは、UTF-8が複数bytesを生成することがあります。
Character: é UTF-8 bytes: C3 A9 Encoded: %C3%A9
Character: ñ UTF-8 bytes: C3 B1 Encoded: %C3%B1
Character: 日 UTF-8 bytes: E6 97 A5 Encoded: %E6%97%A5
Character: 😀 UTF-8 bytes: F0 9F 98 80 Encoded: %F0%9F%98%80Reserved CharactersとUnreserved Characters
RFC 3986はURL charactersをreservedとunreservedのcategoriesに分けています。
Unreserved characters
Letters、digits、hyphen、underscore、period、tildeは安全で、通常encodingは不要です: A-Z a-z 0-9 - _ . ~
Reserved characters
: / ? # [ ] @ ! $ & ' ( ) * + , ; = などはstructural meaningを持つことがあります。syntaxではなくdataとして使う場合はencodeします。
Unsafe or special characters
Spaces、percent signs、quotes、angle brackets、non-ASCII characters、control charactersはencodeするべきです。
よく使われるURL-Encoded Characters
| Character | Encoded | Character | Encoded |
|---|---|---|---|
space | %20 | ! | %21 |
" | %22 | # | %23 |
$ | %24 | % | %25 |
& | %26 | ' | %27 |
( | %28 | ) | %29 |
+ | %2B | , | %2C |
/ | %2F | : | %3A |
? | %3F | = | %3D |
UnicodeとInternational CharactersのEncoding
現代のURLにはinternational textがよく含まれます。characterはまずUTF-8としてencodeされ、その各byteがpercent-encodedされます。
Example: Encoding "café" in a URL
c -> c (ASCII, no encoding needed)
a -> a (ASCII, no encoding needed)
f -> f (ASCII, no encoding needed)
é -> UTF-8 C3 A9 -> %C3%A9
Result: caf%C3%A9
Full URL: https://example.com/search?q=caf%C3%A9Browsersはaddress barに読みやすいcharactersを表示しつつ、実際のrequestではencoded formを送ることがあります。
Programming LanguagesでのURL Encoding
多くのlanguagesにはURL encodingとdecodingのhelpersがあります。
JavaScript
// Encode a single query parameter value
encodeURIComponent("hello world & goodbye")
// "hello%20world%20%26%20goodbye"
// Decode it back
decodeURIComponent("hello%20world%20%26%20goodbye")
// "hello world & goodbye"
// Encode an entire URI while keeping URL structure intact
encodeURI("https://example.com/path?q=hello world")
// "https://example.com/path?q=hello%20world"
// URLSearchParams handles query encoding automatically
const params = new URLSearchParams({ q: "hello world", lang: "en" });
params.toString();
// "q=hello+world&lang=en"Python
from urllib.parse import quote, unquote, urlencode
quote("hello world & goodbye")
# 'hello%20world%20%26%20goodbye'
unquote("hello%20world%20%26%20goodbye")
# 'hello world & goodbye'
urlencode({"q": "hello world", "lang": "en"})
# 'q=hello+world&lang=en'
quote("/path/to/resource", safe="/")
# '/path/to/resource'PHP
// Spaces become %20
rawurlencode("hello world & goodbye");
// "hello%20world%20%26%20goodbye"
// Spaces become + for form-style data
urlencode("hello world & goodbye");
// "hello+world+%26+goodbye"
rawurldecode("hello%20world"); // "hello world"
urldecode("hello+world"); // "hello world"Java
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
URLEncoder.encode("hello world", StandardCharsets.UTF_8);
// "hello+world"
URLDecoder.decode("hello%20world", StandardCharsets.UTF_8);
// "hello world"encodeURIとencodeURIComponent
JavaScriptには似た名前のfunctionsが2つありますが、用途は異なります。
| Function | Use Case | Encodeしないもの |
|---|---|---|
encodeURI() | URL structureを保ったままcomplete URLをencodeする | : / ? # [ ] @ ! $ & ' ( ) * + , ; = |
encodeURIComponent() | 単一のparameter valueまたはpath segmentをencodeする | - _ . ~ ! ' ( ) * |
const value = "price=10¤cy=USD";
// Wrong for parameter values: & and = are not encoded
encodeURI("https://api.com/search?filter=" + value);
// "https://api.com/search?filter=price=10¤cy=USD"
// Server sees two parameters: filter=price=10 and currency=USD
// Correct: encode the value as one component
"https://api.com/search?filter=" + encodeURIComponent(value);
// "https://api.com/search?filter=price%3D10%26currency%3DUSD"
// Server sees one parameter: filter=price=10¤cy=USD目安
query parametersやpath segmentsなどの個別valueにはencodeURIComponent()を使います。encodeURI()は、すでに組み立て済みのfull URLにだけ使います。
URL Encodingでよくある失敗
1. Double encoding
すでにencodedされたtextをさらにencodingすると、percent sign自体が%25になるため%20が%2520になります。dataがURLへ入る境界で一度だけencodeします。
2. Using encodeURI for query values
encodeURIは&や=をencodeしないため、user inputが意図せずextra query parametersになることがあります。valuesにはencodeURIComponentを使います。
3. Confusing + and %20
+はapplication/x-www-form-urlencoded dataではspaceを意味しますが、decodeURIComponentは+を自動でspaceに変換しません。
4. Not encoding file names or path segments
File namesにはspacesやspecial charactersを含められます。URLへ入れる前に各path segmentをencodeします。
const encoded = encodeURIComponent("hello world");
// "hello%20world"
encodeURIComponent(encoded);
// "hello%2520world" <-- wrong, % became %25
const value = "hello world";
const url = "/search?q=" + encodeURIComponent(value);
// Encode once at the boundary// Broken or ambiguous URL
const url = "/files/" + "my report (final).pdf";
// "/files/my report (final).pdf"
// Properly encoded path segment
const url = "/files/" + encodeURIComponent("my report (final).pdf");
// "/files/my%20report%20(final).pdf"Real-World Examples
URL encodingは通常のweb workで常に登場します。
Google Search
https://www.google.com/search?q=what+is+URL+encoding%3F
Spaces become +
Question mark becomes %3FAPI Requests
GET /api/users?name=O%27Brien&city=San%20Francisco
Decoded:
name = O'Brien
city = San FranciscoEmail Mailto Links
mailto:user@example.com?subject=Hello%20World&body=Hi%2C%20how%20are%20you%3F
Decoded:
subject = Hello World
body = Hi, how are you?Redirect URLs
https://auth.example.com/login?redirect=https%3A%2F%2Fapp.example.com%2Fdashboard%3Ftab%3Dsettings
Decoded redirect value:
https://app.example.com/dashboard?tab=settingsURLをすぐにEncode & Decode
無料のURL Encoder & Decoder toolで、任意のURL、query parameter、textをbrowser内ですぐにencodeまたはdecodeできます。
URL Encoder & Decoderを試す参考資料
- Berners-Lee, T., Fielding, R., & Masinter, L. (2005). RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax. https://datatracker.ietf.org/doc/html/rfc3986
- Berners-Lee, T., Masinter, L., & McCahill, M. (1994). RFC 1738 - Uniform Resource Locators (URL). https://datatracker.ietf.org/doc/html/rfc1738
- Mozilla Developer Network. encodeURIComponent() - JavaScript. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
- WHATWG. URL Standard. https://url.spec.whatwg.org/
- Python Software Foundation. urllib.parse - Parse URLs into components. https://docs.python.org/3/library/urllib.parse.html