クエリ文字列

クエリ文字列（クエリもじれつ、）、URLパラメータは、Webサーバに情報を送信するためにURLの末尾につける文字列である。一般に、HTMLの一部として、ページの外観を選択したり、特定のコンテンツの位置にジャンプしたりするために、Webブラウザや他のアプリケーションソフトウェアによってURLに追加されるものを含む。

WebサーバはHTTPリクエストを、URLパスに基づいてファイルシステムからファイルを読み込むか、リソースの種類に応じた方法で処理を行う。特別な処理が呼び出された場合、クエリ文字列はURLのパスコンポーネントとともに、その特別な処理を使用できるようになる。

 構造 
クエリ文字列を含む一般的なURLは次の通りである。

Webサーバはこのようなページへのリクエストを受け取ると、プログラムを実行する。このとき、クエリ文字列（この場合name=ferret）はプログラムの実行に影響を及ぼさない。疑問符 "?" は区切り文字であり、クエリ文字列の一部ではない。

Webフレームワークは、クエリ文字列内の複数のパラメータを何らかの区切り文字で区切って解析する方法を有していることがある。次の例では、複数のパラメータをアンパサンド "&"で区切っている。

クエリ文字列の構造は標準化されておらず、解析方法はWebサイトによって異なることがある。

HTMLでは、ユーザーエージェントがクエリ文字列を生成する3つの方法を定義している。
 要素を使ったHTMLフォーム。
 要素の属性を使用した、構文での。
 HTML5で廃止された要素を用いた検索フォーム。

 Webフォーム 
本来の用途のひとつは、HTMLフォームの内容を格納することである。例えば、フィールドfield1, field2, field3を含むフォームが送信されると、フィールドの内容は以下のようにクエリ文字列としてエンコードされる。

 クエリ文字列は、一連のフィールドと値のペアで構成される。
 各ペア内では、フィールド名と値は等号 "=" で区切られる。
 一連のペアはアンパサンド "&" で区切られる（セミコロン ";" は、W3Cでは推奨されていない）。

明確な基準はないが、ほとんどのWebフレームワークでは、1つのフィールドに複数の値を関連づけることができる（例えば、field1=value1&field1=value2&field2=value3）。

フォームの各フィールドに対して、クエリ文字列はfield=valueのペアを含む。Webフォームには、ユーザーには表示されないフィールドが含まれることがある。これらのフィールドは、フォームが送信されるときにクエリ文字列に含まれる。

この規則はW3Cが推奨しているものである。1999年、W3CはすべてのWebサーバがアンパサンド区切りに加えてセミコロン区切りをサポートし、アンパサンドを用いることなく、HTMLドキュメント内のURLでapplication/x-www-form-urlencodedクエリ文字列を使用できるようにすることを推奨した。2014年以降、W3Cは区切り文字としてアンパサンドのみを使用することを推奨している。

フォーム送信方法がGETの場合、フォームの内容はURLのクエリ文字列にのみエンコードされる。送信方法がの場合、同じエンコーディングが既定として使用されるが、その結果は修正されたURLに含まれるのではなく、HTTPリクエストの本体として送信される。

 インデックス検索 
HTMLにフォームが追加される以前は、ブラウザは要素を一行のテキスト入力コントロールとして表示していた。このコントロールに入力されたテキストは、ベースのURLまたは属性で指定された他のURLへのGETリクエストの追加クエリ文字列としてサーバに送信された。これは、Webサーバが与えられたテキストをクエリの条件として用い、一致するページのリストを返すことができるようにするためのものである。

インデックス検索コントロールに入力されたテキストが送信されると、次のようにクエリ文字列としてエンコードされる。

 クエリ文字列は、テキストをスペースで区切って単語に変換した一連の引数から構成される。
 一連の引数はプラス記号 "+" で区切る。

 URLエンコード 

URLに用いることができない文字（空白文字など）や、URLの中で特殊な意味を持つ文字もある。たとえば、番号記号 "#" を使えば、文書のサブセクション（または）を指定することができる。HTMLフォームでは、等号 "=" が名前と値を区切るのに使われる。URIの汎用的な構文はURLエンコーディングでこれらの文字を回避するが、HTMLフォームはそのような文字すべてにパーセントエンコーディングを適用するのではなく、いくつか追加の置換を行う。

HTML 5では、HTMLフォームをGETメソッドでWebサーバに送信する際の変換を次のように規定している。
 正しい文字コードに変換できない文字は、HTMLの数値文字参照に置き換えられる。
 空白文字は "+" または "%20" としてエンコードされる。
 アルファベット、数字、チルダ "~"、ハイフンマイナス "-"、終止符 "."、アンダースコア "_" はそのままである。
 プラス記号 "+" は "%2B" としてエンコードされる。
 その他の文字はすべて%HHの十六進数でエンコードされ、ASCII以外の文字は最初にUTF-8（または指定された方法）でエンコードされる。

チルダ "~" に対応するオクテットは、ではクエリ文字列で認められているが、HTMLフォームでは "%7E" にパーセントエンコードする必要がある。

 トラッキング 

クエリ文字列を受け取ったプログラムは、その一部または全部を無視することができる。指定されたURLがプログラムではなくファイルに対応する場合、クエリ文字列はすべて無視される。しかし、クエリ文字列が使われているか否かに関係なく、クエリ文字列を含むURL全体がサーバのに保存される。

このことから、HTTP cookieと同様の方法でユーザーを追跡するためにクエリ文字列を使用することができる。これが機能するためには、ユーザーがページをダウンロードするたびに固有の識別子が決められ、そのページが含むすべてのリンクのURLにクエリ文字列として追加されなければならない。ユーザーがこれらのリンクのひとつをたどるとすぐに、対応するURLがサーバにリクエストされる。こうすることで、このページのダウンロードが前のページとリンクされる。

例えば、次のような内容のWebページがリクエストされた場合を考える。
 <a href="foo.html">see my page!</a>
 <a href="bar.html">mine is better</a>

固有の文字列としてe0a72cb2a2c7が選ばれたとすると、Webページは次のように変更される。
 <a href="foo.html?e0a72cb2a2c7">see my page!</a>
 <a href="bar.html?e0a72cb2a2c7">mine is better</a>

クエリ文字列を追加しても、ページの見た目は変わらない。例えばユーザーが最初のリンクをたどると、ブラウザはサーバにfoo.html?e0a72cb2a2c7というページをリクエストし、サーバは?以降を無視してfoo.htmlというページを送り、そのリンクにも同じクエリ文字列を追加する。

こうすることで、このユーザーからのその後のページリクエストはすべて同じクエリ文字列foo.html?e0a72cb2a2c7が追加されることになるため、これらのページがすべて同じユーザーによって閲覧されたということを特定することができる。クエリ文字列は、Webビーコンと連携して使用されることが多い。

トラッキングに用いられるクエリ文字列とHTTP cookieの主な違いは次の通りである。
 クエリ文字列はURLの一部を形成するため、ユーザーがURLを保存したり、他のユーザーに送信したりする場合でも保持される。HTTP cookieは閲覧セッションを跨いで保持することができるが、URLとともに保存または送信されることはない。
 ユーザーが2つ（またはそれ以上）の独立した経路で同じWebサーバに到着した場合、保存されるHTTP cookieは同じものになるが、クエリ文字列は異なるものが割り当てられる。
 ユーザーは設定でHTTP cookieを無効にすることができ、その場合にはトラッキングにHTTP cookieを使用することはできない。一方、クエリ文字列は無効にできないため、トラッキングにクエリ文字列を使用すれば、どのような状況でも機能する。
 ページへのアクセスによって渡されるクエリ文字列が異なると、ブラウザ（プロキシがある場合はプロキシ）のキャッシュからページが提供されることがないため、Webサーバの負荷が増加し、ユーザーエクスペリエンスが低下する。

 互換性の問題 
HTTPの仕様によれば、

とされている。

URLが長すぎる場合、ウェブサーバーはHTTPステータスコード 414 URI Too Longで失敗する。

これらの問題への一般的な対応策は、GETの代わりにPOSTを使い、パラメータをリクエストボディに格納することである。リクエストボディの長さの制限は、一般的にURLの長さの制限よりもはるかに緩い。たとえば、POSTサイズの制限は、デフォルトでIIS 4.0では2 MB、IIS 5.0では128 KBである。Apache2ではLimitRequestBodyディレクティブを使って制限を設定できる。LimitRequestBodyディレクティブはリクエストボディに許容されるバイト数を0（無制限）から2147483647 (2 GB) までで指定できる。

 脚注 

 出典 

 関連項目 
 Common Gateway Interface



 UTMパラメータ

 外部リンク 


Category:Uniform Resource Locator
Category:文字列