広告が嫌いですか? 行く 広告なし 今日

URL エンコード エスケープされるものと、それがなければAPIが破綻する理由

掲載日
URLエンコーディング:エスケープされるものと、それがなければAPIが破綻する理由 1

API呼び出しは正しいように見えました。エンドポイントは一致し、ヘッダーも正しいものでしたが、応答は400 Bad Requestでした。20分間、それを眺め続けた後、問題を見つけました。クエリ文字列に含まれていたメールアドレスに「」が含まれていました。 + サーバーはそれをスペースとして解釈しました。これはURLエンコードの動作であり、問題が実際にデバッグするのが非常に難しい方法です。

このガイドでは、パーセントエンコードが実際に何をやっているか、どの文脈でどの文字をエンコードすべきか、JavaScriptでよく見られる罠、そしてURLエンコーダーのようなツールを使って自分の作業をチェックする方法について説明します。 URLエンコーダー/デコーダー を使用してください。

URLエンコードが実際に何をやっているか

URLにはASCII文字の一部しか含まれることができません。それ以外のもの——スペース、国際文字、URLで特別な意味を持つ記号——は送信前に安全なフォーマットに変換される必要があります。

パーセントエンコードは、それぞれの危険なバイトをパーセント記号と2桁の16進数で置き換えることでこれを実現します。スペースは %20、ハッシュは %23、フォワードスラッシュは %2Fになります。名前はその先頭のパーセント記号から来ています。

規格(RFC 3986)では、「未制限文字」と呼ばれる文字がエンコードを必要としないと定義されています。それはアルファベット(A-Z、a-z)、数字(0-9)および4つの記号です。 - _ . ~。それ以外のすべては、構造を区切り用に使う「制限文字」またはエンコードする必要があります。

APIを壊す文字

実際の問題で最も被害を与えるものリストです。

文字 エンコード済み エンコードが必要な文脈 注記
空間 %20 すべての文脈 もしくは + フォームデータにおいて——以下を参照
%26 クエリ文字列の値 クエリパラメータを分離する;値の中ではエンコードする必要があります
= クエリ文字列の値 キーと値を分離する;値自体にエンコードする必要があります
+ クエリ文字列の値 フォームエンコードでスペースとして解釈される—— %2B で、プラス記号を文字通りに表します
# %23 パス、クエリ文字列 フラグメントをマークする;それ以降のすべてはサーバーに送られない
? パスセグメント、クエリ値 クエリ文字列を開始する;パスまたは値にエンコードする必要があります
/ パスセグメント(文字通り) パスセグメントを分離する;セグメント値の中に入れてエンコードする必要があります
@ %40 クエリ文字列の値 クエリパラメータ内のメールアドレスはこのようにエンコードする必要があります

3つの文脈、異なるルール

エンコードする部分がURLの構造を変えるため、何をエスケープする必要があるかが変わります。

完全なURL — 完全なURLを渡す場合、構造を維持したいので、スラッシュ、質問マーク、ハッシュ記号はそのまま残します。許容されない文字だけがエンコードされます。

クエリ文字列の値 — これは多くのAPIのバグが生じる場所です。クエリ文字列内の各値は、構造を形成するための文字(&, =, #, +)が値に字面として現れないようにエンコードされる必要があります。ユーザー名が「John & Jane」の場合、クエリ文字列は name=John%20%26%20Jane、ではなく name=John & Jane (サーバーはこれで2つのパラメータとして解析します)。

パスセグメント — パスセグメントはスラッシュの間の部分です。セグメントにスラッシュが含まれている場合(たとえば、ファイル名にスラッシュがある場合)、それを %2Fとしてエンコードする必要があります。一部のサーバーはパス内の %2F をセキュリティ上の懸念として扱います;バックエンドを理解してから使用してください。

encodeURI と encodeURIComponent — JavaScriptの罠

JavaScriptには2つの組み込みエンコード関数があります。間違った関数を使うことは非常に一般的なバグです。

// encodeURI — encodes a full URL
// Preserves: : / ? # [ ] @ ! $ & ' ( ) * + , ; =
encodeURI("https://example.com/search?q=hello world&lang=en")
// → "https://example.com/search?q=hello%20world&lang=en"
// Note: & and = are NOT encoded — the query structure is preserved

// encodeURIComponent — encodes a single value
// Encodes everything except: A-Z a-z 0-9 - _ . ! ~ * ' ( )
encodeURIComponent("hello world&lang=en")
// → "hello%20world%26lang%3Den"
// Note: & and = ARE encoded — safe to use as a query value

// The bug: using encodeURI on a value
encodeURI("hello world&lang=en")
// → "hello%20world&lang=en"  ← & survives! Server sees two parameters.

// The correct approach for building query strings
const name = "John & Jane"
const email = "john+jane@example.com"
const url = `https://api.example.com/users?name=${encodeURIComponent(name)}&email=${encodeURIComponent(email)}`
// → "https://api.example.com/users?name=John%20%26%20Jane&email=john%2Bjane%40example.com"

ルール:個々の値に encodeURIComponent を使用してURLに組み込む前にエンコードしてください。完全なURLをもつ場合で構造を破らないようにするには、 encodeURI のみを使用してください。

プラス記号:フォームエンコードとパーセントエンコード

HTMLフォームが method="GET"を送信する場合、ブラウザはデータを application/x-www-form-urlencodedでエンコードします。このフォーマットでは、スペースは + の代わりに %20に変換されます。多くのサーバーフレームワーク(PHP、Django、Rails)はクエリ文字列内で + をスペースとして自動的に解釈します。

値にプラス記号が実際に含まれている場合(例:電話番号 +44 7700 900000)に問題が生じます。もしそれを +44...として渡すと、サーバーは先頭のプラスをスペースとして解釈し、 44...を得ます。解決策は、文字通りのプラス記号を %2Bとしてエンコードすることです。これにより、どちらの解釈スキームでもそのまま保存されます。

現代のAPI作業では、スペースを %20encodeURIComponent が生成するもの)として使用し、 +.

に頼らないようにしてください。

二重エンコード:エンコードが間違った場合 %20 二重エンコードは、すでにエンコードされたものに再度エンコードするときに起こります。 %2520 自身が %25 にエンコードされ、サーバーは %20 を文字通りのパーセントとして解釈し、スペースではなく

を取得します。

  • これは次のケースで現れます:
  • データベースにURLを保存し、それを使用する前に再度エンコードする
  • フレームワークまたはライブラリがすでに手動でエンコードした値をエンコードする

パラメータとして別のURLを含むURLを作成する decodeURIComponentこれを避けるには、URLを構成するときにちょうど1回エンコードしてください。値がすでにエンコードされているかどうかわからない場合は、まず

で解釈し、その後、きれいに再エンコードしてください。

開発ツールでURLエンコードをデバッグする

APIリクエストが不正に動作する場合、開発ツール(F12)を開き、ネットワークタブに移動し、失敗したリクエストをクリックします。ヘッダーの下で、リクエストURLを見つけて、ブラウザはそのエンコードされた形式で表示します。パラメータの下では、クエリパラメータが元の値に戻された形で表示され、アンパースンドが分離されたか、または文字通りに渡されたかを簡単に確認できます。 IO Tools URL エンコーダー/デコーダー 両方向を処理し、出力がすぐに表示されます。

広告なしで楽しみたいですか? 今すぐ広告なしで

拡張機能をインストールする

お気に入りのブラウザにIOツールを追加して、すぐにアクセスし、検索を高速化します。

に追加 Chrome拡張機能 に追加 エッジ拡張 に追加 Firefox 拡張機能 に追加 Opera 拡張機能

スコアボードが到着しました!

スコアボード ゲームを追跡する楽しい方法です。すべてのデータはブラウザに保存されます。さらに多くの機能がまもなく登場します!

ニュースコーナー 技術ハイライト付き

参加する

価値ある無料ツールの提供を継続するためにご協力ください

コーヒーを買って