YamlBox

ウェブとエンコーディング · 5 分で読みました

URL エンコード: いつ逃げるか、いつ物事を壊すか

URL は、パーサーにとって意味のある文字と、単なるデータである文字から組み立てられます。パーセント エンコーディングは、この 2 つを区別する方法です。 URL エンコーダは後者を `%XX` エスケープに変換するため、`&`、`?` またはスペースを含む値はトリップ後も残ります。ほとんどの URL バグはエンコードの失敗ではありません。間違った部分をエンコードしたり、二度エンコードしたりしています。

更新されました

エンコードする必要があるもの

少数の文字セット (文字、数字、`-`、`_`、`.`、`~`) は常に安全です。それ以外はすべて予約されているか、エスケープする必要があります。予約文字は興味深いものです。予約文字は、URL では有効ですが特定の位置でのみ使用できるためです。`?` はクエリを開始し、`&` はパラメータを分離し、`=` は値を割り当て、`#` はフラグメントを開始し、`/` はパス セグメントを分離します。これらの 1 つをエンコードされていない値の中に置くと、その構造を黙って書き換えることができます。

プラスまたは %20

宇宙はその典型的な例です。パス内のスペースは `%20` でなければなりません。 a `+` は文字通りのプラスです。フォーム パーサーによって読み取られる `application/x-www-form-urlencoded` 本文およびクエリ文字列では、`+` はスペースとして認識されます。この相違が、値が、あるコンテキストでは機能し、別のコンテキストでは機能しないものにエンコードできる理由であり、デコーダーが両方の解釈を提供する理由です。

URL 全体ではなくコンポーネントをエンコードします。コンポーネント エンコーダを介して完全な URL を実行すると、それ自身の `://` および `?` がエスケープされ、何も解決されないリンクが生成されます。

誰もが理解できる JavaScript の違い

                encodeURI('https://x.com/a b?q=1')        // keeps :// ? = — for a whole URL
encodeURIComponent('a b?q=1')               // escapes ? and = — for one value
              

`encodeURI` は URL 構造を保持し、完全なアドレスを意味します。 `encodeURIComponent` は重要なものをすべてエスケープし、単一のパラメータ値を意味します。間違ったものを使用すると、壊れた URL かエスケープされていない値が生成され、リンクが 404 になるかクエリ文字列のパラメータの半分が失われるなど、症状は逆になります。

二重エンコードと署名付き URL

すでにエンコードされた値をエンコードすると、`%20` は `%2520` に変わり、サーバーはそれを 1 回デコードして、スペースが意図されていた場所にリテラルの `%20` をアプリケーションに渡します。これは階層化されたシステムに現れます。プロキシはターゲットを再エンコードし、クライアントはすでに受信した 3 をエスケープします。これは署名付き URL にとって最も重要です。署名は正確にエンコードされた文字列に基づいて計算されるため、1 文字のエスケープを変更すると、同じリソースに解決される場合でもリンクが無効になります。

デコードしてデバッグする

リンクに障害が発生した場合、サーバーが実際に何を要求しているのかを確認するにはリンクをデコードするのが最も早い方法であり、多くの場合、その答えは構造内に漏洩した値です。ブラウザで作業するということは、トークン、署名付きパラメータ、または顧客 ID を含む URL を、どこにも送信せずに貼り付けることができることを意味します。これはまさに、リクエストを記録するサービスに貼り付けるべきではない種類の URL です。

URL エンコーダ/デコーダ — よくある質問

スペースは %20 にする必要がありますか、それともプラス記号にする必要がありますか?

パスおよび自分で構築する URL では `%20` を使用します。どちらもクエリ文字列では有効であり、フォーム パーサーは従来 `+` をスペースとして読み取ります。デコードでは、どの規則によって文字列が生成されたかを知る必要があります。

URL を 2 回エンコードすると壊れるのはなぜですか?

各パスはエスケープ文字をエスケープします。スペースは `%20` になり、次に `%2520` になります。到着時にサーバーは一度デコードし、アプリケーションはリテラル `%20` テキストを受け取ります。生の値が URL の一部になる時点で 1 回エンコードします。

encodeURI と encodeURIComponent の違いは何ですか?

`encodeURI` は、`://`、`?`、`&`、`=` などの構造文字をそのまま残すため、アドレス全体に適します。 `encodeURIComponent` はそれらもエスケープするため、単一のパラメータ値に適合します。これらを混同すると、生成されたリンクが壊れる原因のほとんどが発生します。

この投稿で言及されているツール

19 ツールの完全なリストを参照する

さらに読む記事

すべての 19 投稿 →