開発者ツール · URL エンコーダーとデコーダー
URL コンストラクターがエンコードするもの: ブラウザーのパーセント エンコード セット
· 仕組み
URLエンコーディング JavaScript なんてことだ ウェブ API
URL API は、URL のどの部分に到達するかに応じて、一部の文字をサイレントにパーセント エンコードし、その他の文字はそのままにします。この投稿では、WHATWG エンコード セットと出力を予測する方法について説明します。
%20 になったスペースと |残ったもの — new URL() がパスを部分的にエンコードした具体的なケース
新しい URL("https://example.com/hello world") が実行されると、スペースは静かに %20 になります。ただし、 new URL("https://example.com/hello|world") ではパイプはそのまま残ります。この違いはランダムではありません。WHATWG URL 標準では、URL コンポーネントごとにエンコードする個別の文字セットが定義されています。パス、クエリ、フラグメント、ユーザー情報にはそれぞれ独自のルールがあります。これらのセットを理解するということは、コンストラクターが何を行うかを予測することを意味します。
HTTP 上では安全ではなく、可読性が損なわれるため、スペースにはパーセント エンコードが必要です。パイプは異なります。構造を分割する予約文字ではないため、ブラウザはパイプをそのままにしておきます。安全性と読みやすさの間の境界線は、推測ではなく、WHATWG によって引かれます。 「hello world」をテストするとエンコーディングが示されます。 「hello|world」をテストすると、URL の各部分の境界が明らかになります。
1 つの URL、複数のエンコード セット - パス、クエリ、フラグメント、およびユーザー情報のそれぞれに、エスケープする独自の文字リストがあります。
1 つの URL には複数の領域が含まれており、それぞれに独自のエンコード ルールがあります。パスは 1 つのセットに従い、別のセットをクエリし、3 番目のフラグメント、4 番目の userinfo をたどります。パスとクエリではスペースが %20 になります。等号はクエリ内に残り、キーと値を区切りますが、encodeURIComponent はそれを %3D に変換します。 URL コンストラクターはそのコンテキストを認識し、各部分に正しいルールを適用します。
エンコード セットは正確で小さいです。パスには独自の文字リストがあります。クエリには似ていますが異なるリストがあります。これは、どの文字が構造的な意味を持っているかを反映します。スラッシュはパス セグメントを分割するため、encodeURIComponent はそれを %2F としてエンコードします。フラグメント内では、スラッシュは何も分割せずに存在できます。 WHATWG ルールを理解するということは、コードを実行せずに出力を予測することを意味します。
パーセントエンコーディングが一方向である理由: エンコードされたままのものはそのまま残ります
URL コンストラクターは一方向の正規化を実行します。 「%20」を新しい URL に渡すと、変更されない %20 が生成されます。コンストラクターは、それがすでにエンコードされているものとして認識し、そのままにしておきます。これが、二重エンコーディングが重要である理由です。一度エンコードし、コンストラクターを通過すると、エンコーディングは維持されます。コンストラクターは、デコード、再解釈、および再エンコードを行いません。先へ読み進められます。
この一方向プロパティは、URL.href を正規のものとして信頼するアプリケーションに影響します。ユーザー入力をパスと連結すると、入力は正規化されますが、デコードされません。 「my+file」のような値はそのまま残りますが、コンテキストによっては「my%2Bfile」になります。 decodeURIComponent を使用する後のコードは、フォーム データからのプラスをスペースとして読み取る可能性があります。コンストラクターは一度正規化します。その後、あなたの価値は固定されます。
実用的な例: new URL() を介して同じ乱雑な文字列を渡し、href、pathname、searchParams を読み取る - 3 つの異なるビュー
「hello world&foo=bar|test#anchor」を取得し、さまざまなコンポーネントを含む新しい URL に挿入します。スペースはどこでも %20 になります。パス内のアンパサンドは残ります (構造的な意味はありません) が、クエリでもアンパサンドは残ります (パラメータを区切るため、正規化すると「q=」と「foo=bar」の間の境界が失われます)。パイプとハッシュは場所によって動作が異なります。
href、pathname、searchParams を読み取ると、3 つの異なるビューが表示されます。 pathname は、スキーム、ホスト、またはクエリを含まないエンコードされたパスを示します。 searchParamsはデコードされたパラメータを与えるため、フォームデータの「hello+world」はスペースになります。検索プロパティはリテラル文字列を保持します。 href は完全な正規化された URL を示します。これらは 1 つのオブジェクト上に共存します。どちらを使用するかは、次のステップによって異なります。
URLSearchParams とフォーム エンコーディング ルール - パス名では %20 が生成されるのに、スペースには + が生成される理由
URLSearchParams はフォーム エンコーディングを適用します。スペースは %20 ではなくプラスになります。 new URLSearchParams({q: "hello world"}) は、「q=hello%20world」ではなく、「q=hello+world」を生成します。これは、歴史的な application/x-www-form-urlencoded ルールです。ただし、この文字列を生のクエリとして新しい URL に渡すと、プラスはプラスのままです。 URLSearchParams のみがスペースとしてデコードします。コンストラクターは、表示されたものに忠実です。
このプラス記号の違いにより、一般的なバグが発生します。アドレス バーの URL では、スペースに %20 が使用されます。フォームデータはプラスを使用します。 URLSearchParams.get の代わりに decodeURIComponent (文字通りプラスと読みます) を使用してデコードすると、スペースはプラス文字になります。 URL エンコーダとデコーダは、「hello+world」を貼り付けることと、コンポーネント モードとフォーム モードを比較してスペースが表示される場所を確認することの両方を表示します。
encodeURI との比較 — 2 つが一致する部分と相違する部分
URL コンストラクターと encodeURIComponent は別のツールです。 encodeURIComponent は、予約されていない文字、数字、および - _ を除くほとんどすべてをエンコードします。 ! ~ * ' ( )。コンテキストを前提としません。 URL コンストラクターは実際の URL を解析し、コンポーネントごとに WHATWG ルールを適用します。 encodeURIComponent は、「hello/world"」を「hello%2Fworld」に変換します。新しい URL では、スラッシュがパス区切り文字として認識されます。入力は同じですが、出力は異なります。
部分を連結して URL を構築する場合は、encodeURIComponent を使用します。完全な URL または部分的な URL には、URLSearchParams または URL コンストラクターを使用します。 URL 全体に対して encodeURIComponent を使用しないでください。計画を台無しにすることになります。結果を意図と比較します。ブラウザは URL 構造の意見を強制し、新しい URL はそれを実装します。 URL エンコーダとデコーダは、両方のビューを並べて表示します。
これでカバーされないもの — ホスト解析、IDNA、特殊なスキームと特殊でないスキーム
WHATWG URL Standard は真実の情報源ですが、これを読むには忍耐が必要です。エンコード セットは、単純なリストではなく、アルゴリズム フラグメントで定義されます。実際には、セットを暗記するよりも原理を理解することが重要です。パスではさらに多くの文字が許可されます (スラッシュは構造的です)。クエリには独自のルールがあります。フラグメントには最も制限が少ない (クライアント側で処理され、サーバーには送信されない)。各コンポーネントには独自のルールがあります。これがわかれば、どこを見るべきかがわかります。
正規化と検証は異なる境界です。コンストラクターは正規化します。パーセント エンコーディングをクリーンアップし、コンポーネント ルールを適用し、正規形式を与えます。検証は行われません。無効な文字はスローされますが、空のホストは受け入れられます。コンストラクターは形式については厳密ですが、解釈については寛大です。正確な仕様準拠については、WHATWG のパーセントエンコードされたバイトのセクションをお読みください。日常的な構築には、URLSearchParams、URL API、および実際の例を使用してください。
要点: パーサーにも意見がある — URL エンコーダーとデコーダーが値またはアドレスの単純なパーセント エンコーディングを表示して、ブラウザーが生成したものと比較できるようにする方法
ここでサポートされていない WHATWG 機能には、IDNA 変換 (国際ドメイン名から ASCII) へのホスト解析、特殊スキームと非特殊スキームの処理が含まれます。ファイル: URL は二重スラッシュ権限を使用します。データ: URL にはありません。コンストラクターはこれらのルールを強制します。ホスト名の変換と特別なステータスの決定は、パーセント エンコーディングではなく仕様の読み取りに属します。これは、異なるスキーム間で URL を構築する場合に重要です。
ブラウザーの解釈と期待値を比較して、URL の構築をテストします。新しい URL を使用してビルドし、重要なプロパティを読み取ります。完全な形式の場合は href、パスの場合は pathname、生のクエリの場合は検索、デコードされた場合は searchParams です。出力に驚いた場合は、URL エンコーダとデコーダに貼り付けて、変換を段階的に実行してください。このツールは、正規化された出力を生のエンコードと並べて表示し、違いを明らかにします。 WHATWG セットを理解するということは、ブラウザーの選択とそれらの操作方法を理解することを意味します。