URLエンコーディング詳細解説:とはパーセントエンコーディング
毎回あなたクリックするリンク、送信表単または入力する网址时,あなたのブラウザすべてで幕後処理する URLエンコーディング。あなたで URL 中看までのそれらの由百分号と16進数数値構成するの神秘文字列かつ非随机;それ们は一種の精心設計するの机制,させる互联网信頼できる実行する。理解する URLエンコーディングに対して Web 開発者、API 設計する者と任意のから事 Web 技术工作の人来说すべて非常に重要です。このガイド説明するた URLエンコーディングとは何か、なぜ存で、どのように工作ならびにあなた理解する必要がありますのセキュリティへの影響。
URLエンコーディングとは?
URLエンコーディング,正式名と呼ばれるパーセントエンコーディング,は RFC 3986 中定義するの一種の机制,する字符変換するのために可で统一资源标识符(URI)中安全転送するのフォーマット。URL 仕様仅許可する ASCII 字符の子集直接出今 URL 中。任意の不で此許可する集合中の字符必須エンコードするのために百分号(%)後跟两个16進数数値,表示该字符の字节值。
< に変わる %3C,なぜなら < の ASCII 码は 60,16進数のために 3C。
URLエンコーディングが必要な理由
URL を持つ使用某些字符として分隔符の特定構文。问号 ? する路径とクエリする文字列分隔。& 符号分隔クエリする参数。など号 = 分隔参数名と值。正斜杠 / 分隔路径段。もしこれらの字符出今転送するのデータ中,それ们できるられる误解のために URL 结构そして非内容。
考慮する用户でWebサイト上検索する "rock & roll" 时できる发生何么。不エンコードするの话,URL できるは /search?q=rock & roll。ブラウザできるする & 説明するのためにクエリするパラメータデリミタ,するクエリする分割するのために两个参数:q=rock と名のために roll の第二个参数(なし值)。URLエンコーディング修正たこの问题:/search?q=rock%20%26%20roll。
パーセントエンコーディングの仕組み
エンコードするたことがある程従う URI 仕様定義するの簡単アルゴリズム:
- 识别非予約文字:字符 A-Z、a-z、0-9、-、.、_ と ~ は非予約の。それ们から必要ないエンコードする,可直接出今 URL 中。
- 识别予約文字:字符 :、/、?、#、[、]、@、!、$、&、'、(、)、*、+、,、; と = はのために URL 構文予約の。時にそれ们用作データそして非分隔符时必須エンコードする。
- その他すべての文字をエンコード:任意の不で非予約または予約集合中の字符必須入行パーセントエンコーディング。これには以下が含まれますスペース、制御する字符、非 ASCII 字符と任意の ASCII 範囲以外の字符。
非ASCII文字のエンコーディングプロセス
非 ASCII 字符(如重音字母、中日韩字符と表情符号)必要とする额外步骤。まず,する字符変換するのために其 UTF-8 字节序列。それから各字节単独入行パーセントエンコーディング。これは以下を意味します単个字符かもしれない生み出す多个パーセントエンコーディング三元组。
例えば,欧元符号(€)の UTF-8 字节序列のために E2 82 AC。URLエンコーディング後に変わる %E2%82%AC。汉字"中"の UTF-8 序列のために E4 B8 AD,生み出す %E4%B8%AD。表情符号😀(笑脸)あり 4 字节 UTF-8 序列,エンコードするのために %F0%9F%98%80。
よく使われるエンコード文字
下表表示するた最も一般的の URLエンコーディング字符:
| 字符 | エンコードする | ASCII 码 | 理由 |
|---|---|---|---|
| スペース | %20 | 32 (0x20) | URLでは許可されない |
| ! | %21 | 33 (0x21) | 予約(サブデリミタ) |
| # | %23 | 35 (0x23) | 予約(フラグメントデリミタ) |
| $ | %24 | 36 (0x24) | 予約(サブデリミタ) |
| & | %26 | 38 (0x26) | 予約(クエリデリミタ) |
| ' | %27 | 39 (0x27) | 予約(サブデリミタ) |
| ( | %28 | 40 (0x28) | 予約(サブデリミタ) |
| ) | %29 | 41 (0x29) | 予約(サブデリミタ) |
| + | %2B | 43 (0x2B) | 予約(クエリ内のスペース) |
| , | %2C | 44 (0x2C) | 予約(サブデリミタ) |
| / | %2F | 47 (0x2F) | 予約(パスデリミタ) |
| : | %3A | 58 (0x3A) | 予約(プロトコルデリミタ) |
| ; | %3B | 59 (0x3B) | 予約(パラメータデリミタ) |
| = | %3D | 61 (0x3D) | 予約(値デリミタ) |
| ? | %3F | 63 (0x3F) | 予約(クエリデリミタ) |
| @ | %40 | 64 (0x40) | 予約(認証デリミタ) |
| [ | %5B | 91 (0x5B) | 予約(IPv6リテラル) |
| ] | %5D | 93 (0x5D) | 予約(IPv6リテラル) |
URLエンコーディングとHTMLエンコーディング
URLエンコーディングと HTML エンティティエンコードするよくられる混淆,しかしそれ们の用途完全異なる,実行するで異なるのコンテキスト中。
URLエンコーディング
URLエンコーディングする字符変換するのために %XX フォーマット,するためにで URL 中安全転送する。それ由 RFC 3986 仕様,適用する于 URL コンポーネント如路径、クエリする文字列と片段。
HTMLエンコーディング
HTMLエンコーディングする字符変換するのためにエンティティ引用する如 &、< と >,するためにで HTMLドキュメント中安全レンダリングする。それ防止するブラウザする内容説明するのために HTML マークする。HTMLエンコーディング由 HTML 仕様仕様。
主な違い
| 側面 | URLエンコーディング | HTMLエンコーディング |
|---|---|---|
| コンテキスト | URL と URI | HTMLドキュメント |
| フォーマット | %XX(パーセント + 16進数) | または NNN; |
| < の例 | %3C | < |
| & の例 | %26 | " の例 |
| %22 | " | 目的 |
| 安全なURL転送 | HTMLインジェクションの防止 | 仕様 |
| RFC 3986 | HTML Living Standard | HTML Living Standard |
(HTMLエンコーディングの & 符号)。两者すべて有効,しかし URLエンコーディング & 符号はより正しくの做法,なぜならそれ予約たデータの预期意味。
各プログラミング言語でのURLエンコーディング
毎種類主にプログラミング言語すべて提供する URLエンコーディングとデコードするの内置函数。しかし,确切の行のために各不同じ,理解する差异正避ける間違い非常に重要です。
JavaScript
JavaScript 提供する三个エンコードする函数,各行のために異なる:
// 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 correctly主な違いで于 encodeURI 予約 URL 结构字符,そして encodeURIComponent エンコードするすべての内容。時にあなたあり完全 URL 时使用 encodeURI,エンコードする単个参数值时使用 encodeURIComponent。
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"スペース文字:%20 と +
スペース字符あり两種類常见エンコードする,理解する何时使用毎種類エンコードするとても重する必要がある:
- %20:RFC 3986 定義するの標準パーセントエンコーディング。これは URL 路径コンポーネント中スペースの正しくエンコードする,常に安全。
- +(加号):由 application/x-www-form-urlencoded 媒体タイプ定義する,に使用されるエンコードするクエリする文字列中の表単データ。で此エンコードする中,スペース置換するのために加号,加号本身エンコードするのために %2B。
この違いとても重する必要がある,なぜならする + デコードするのためにスペース仅で application/x-www-form-urlencoded データのコンテキスト中は正しくの。で URL 路径コンポーネント中,+ は字面加号,いいえスペース。大多数のサーバー端フレームワーク正クエリする文字列処理する正しく,しかしでエンコードする路径または使用カスタマイズする URL 方案时かもしれないをもたらす細微間違い。
セキュリティへの影響
URLエンコーディングを持つ重する必要があるのセキュリティへの影響,各 Web 開発者すべて必須理解する。
二重エンコーディング攻撃
二重エンコーディング发生でデータられる URLエンコーディング多次时。攻撃者かもしれない送信 %2527,それで第一次デコードする时に変わる %27,第二次デコードする时に変わる単引号 '。もし安全フィルター器だけ確認する第一次デコードする,すぐにできる遗漏悪意のある字符。これできる绕たことがある入力検証、跨站脚本(XSS)フィルター器と SQL 注入防护。