URI - Uniform Resource Identifiers

この頁では、URIとは何か、URLの違い、そしてHTTPで使用するURIについてなどを解説します。

URIとは

はじめに

HTTPの仕様書であるRFC 2616には、URI (Uniform Resource Identifiers)という単語が現れます。 RFC 2616のsection 3.2をご覧ください。

URI とは、既に多くの名前で、例えば WWW address, Universal Document Identifier, Universal Resource Identifier, そして、最終的に Universal Resource Locator (URL) と Name (URN) という名で知られている。 HTTP に限って言えば、Uniform Resource Identifier とはリソースを名前や場所、その他の特徴で識別する簡潔に書式化された文字列の事である。

このリソースを名前や場所、その他の特徴で識別する簡潔に書式化された文字列という概念は、WWWの生みの親であるTim Berners-Leeが1991年に発表した論文が元になっています。 1994年には、その仕様を議論するための“IETF URI working group”が設立され、RFCとして発行されたものはUniversal Resource Identifiers in WWW: A Unifying Syntax for the Expression of Names and Addresses of Objects on the Network as used in the World-Wide Web.が最初です。 その後、仕様が更新・改訂され、現在はUniform Resource Identifier (URI): Generic Syntaxが最新となっています。 そのsection 1.1をご覧ください。

URI は、以下のように特徴付けられる:

統一書式 {Uniform}
統一書式性にはいくつかの利点がある。 異なる型のリソース識別子を同じ状況の中で、例えそれらの資源にアクセスするためのメカニズムが異なっていても、使う事ができる。 異なる型のリソース識別子に共通した構文の慣習を、同一の意味論で解釈できる。 既に存在する識別子が使用する方法を妨げる事無く新たな型のリソース識別子を導入できる。 識別子をさまざま異なった状況で再利用でき、それゆえ新たなアプリケーションやプロトコルは既に存在する、巨大で広く用いられているリソース識別子の集合を活用できる。
リソース {Resource}
この仕様書では、リソースであるものの範囲を制限しない; むしろ、"リソース" という用語は、URI によって識別される全てのものについて一般的な意味において使用される。 よく知られた例としては、電子文書、画像、一貫性のある目的をもつ情報源 (例えば、"本日のロサンゼルスの天気予報")、サービス (例えば、HTTP から SMS へのゲートウェイ)、またその他のリソースの集合等がある。 リソースは、インターネットを通じてアクセス可能である必要はない; 例えば、人間、企業、及び図書館にある装丁された書籍も、リソースとみなす事ができる。 同様に、数学の方程式の演算子やオペランド、関係の種類 (例えば、"親" や "会社員")、あるいは数値 (例えば、"0" や "1", "無限大") のような、抽象的な概念もリソースとなりうる。
識別子 {Identifier}
識別子は、識別の範囲内の他の全てのものから特定されている事を区別するために必要な情報を具体化する。 我々は、"識別" や "識別する" という用語を、あるリソースを他の全てのリソースから区別する目的のために用い、その目的がどのように (例えば、氏名、住所、あるいは状況によって) 達成されるかにかかわらない。 これらの用語は、識別子が、いくつかの識別子の場合ではそうでなくても、参照されるものの識別を定義する、あるいは具体化するという事の前提であると誤用されるべきではない。 また、URI を使用するシステムがリソースを識別してアクセスするという事を仮定すべきではない: 多くの場合、URI は、それらがアクセスされるといういかなる意図もなしにリソースを表すために使用される。 同様に、識別される "一つの" リソースは、本質的に唯一である必要はない (例えば、リソースとは、名付けられた一式のもの、あるいは時間経過と共に変化するものへの写像でありうる)。

すなわち、URIとは「統一された書式を持った、リソースを識別するための文字列」であると言うことができます。 「統一された」とある通り、URIはHTTPだけで使用される概念ではなく、他のプロトコルやサービス、あるいはファイルシステムでも使用されます。 RFC 3986中の例をご覧下さい。 これらはすべてURIです。

 ftp://ftp.is.co.za/rfc/rfc1808.txt

 http://www.ietf.org/rfc/rfc2396.txt

 ldap://[2001:db8::7]/c=GB?objectClass?one

 mailto:John.Doe@example.com

 news:comp.infosystems.www.servers.unix

 tel:+1-816-555-1212

 telnet://192.0.2.16:80/

 urn:oasis:names:specification:docbook:dtd:xml:4.1.2

“URI”と“URL”の違い

ところで、URIに似た語でURLというなる語もありますが、この二つは何が違うのでしょうか? その違いについても、RFC 3986の中に記述されています。 Section 1.1.3をご覧ください。

URI は、それが位置指定子か、名前か、あるいはその両方かという点において、更に分類できる。 "Uniform Resource Locator" (URL) という用語は、リソースを識別するのに加えて、その主なアクセスメカニズム (例えば、そのネットワーク上の "位置") を記述する事によってリソースの場所を見つける方法を提供するような、URI の部分集合を指す。 "Uniform Resource Name" (URN) という用語は、例えそのリソースが存在しなくなったり、あるいは利用不可能になっても全体において一意で永続的である事が要求される "urn" スキーム [RFC2141] の下での両方の URI、また名前の特性を持つあらゆる他の URI を参照するために歴史的に使用されている。

個々のスキームは、"名前" あるいは "位置指定子" のどちらか一方に分類される必要はない。 あらゆる与えられたスキームからの URI の例でも、名前、位置指定子、あるいは両方の特性を持っているかもしれないし、これはしばしばスキームのどんな品質よりも、命名の権威{naming authority} による識別子の割り当てにおける永続性と配慮に依存する。 将来の仕様書や関連文書では、より制限された用語である "URL" や "URN" よりも一般的な用語である "URI" を使用すべきである [RFC3305]。

これらをまとめると、以下のようになります。

URIは、リソースを識別するための文字列(Identifier)全般を指し、URL及びURNの上位集合
URLは、リソースのある位置(Locator)を指定するもの
URNは、リソースの名前(Name)を指定するもの

HTTPで使われるURIについて

HTTP URIの構造

それでは、HTTPで使うURIにはどのような決まりがあるのでしょうか? まず、RFC 2616のsection 3.2.2をご覧ください。

"http" スキームは HTTP プロトコル経由でネットワークリソースの位置を指すために使われる。 この節では http URL について、スキーム特有の構文と意味論を定義する。

 http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]

もし、port が空かあるいは与えられていなければ、ポート 80 が仮定される。 その意味論は、識別されるリソースはそのホストのそのポートで TCP 接続のためのリスニングをしているサーバ上にあり、リソースに対すする Request-URI は、abs_path である (section 5.1.2)。 できれば、URL での IP アドレスの使用は避けるべきである (RFC 1900 参照)。 もし、abs_path が URL で与えられていなければ、そのリソースへの Request-URI として使われる時に、"/" が与えられなければならない (section 5.1.2)。 もし、プロクシが fully qualified domain name ではない ホストネームを受けとったならば、プロクシは自分のドメインにそのホストネームを追加する事ができる。 もし、プロクシが fully qualified domain name を受けとったならば、プロクシは絶対にホストネームを書き換えてはならない

ここで、http URLと書かれていることに注目してください。 ここは歴史的経緯からそうなっているのですが、実際問題としてHTTPのみに限って言えば、URIとURLはほぼ同じ意味を持ちます。

(※) 特に「位置指定子」という意味を強調したい場合には“URI”が使用されますが、それ以外の場面で、たとえば一般の人にWebサイトの「場所」を指し示すための言葉としては、すでに広く認知されている“URL”を使っても間違いではありません。

上記中のhost, port, abs_path, queryなどの定義については、RFC 2396の付録A.において、拡張BNFで記述されています。

 URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
 absoluteURI   = scheme ":" ( hier_part | opaque_part )
 relativeURI   = ( net_path | abs_path | rel_path ) [ "?" query ]

 hier_part     = ( net_path | abs_path ) [ "?" query ]
 opaque_part   = uric_no_slash *uric

 uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
                 "&" | "=" | "+" | "$" | ","

 net_path      = "//" authority [ abs_path ]
 abs_path      = "/"  path_segments
 rel_path      = rel_segment [ abs_path ]

 rel_segment   = 1*( unreserved | escaped |
                     ";" | "@" | "&" | "=" | "+" | "$" | "," )

 scheme        = alpha *( alpha | digit | "+" | "-" | "." )

 authority     = server | reg_name

 reg_name      = 1*( unreserved | escaped | "$" | "," |
                     ";" | ":" | "@" | "&" | "=" | "+" )

 server        = [ [ userinfo "@" ] hostport ]
 userinfo      = *( unreserved | escaped |
                    ";" | ":" | "&" | "=" | "+" | "$" | "," )

 hostport      = host [ ":" port ]
 host          = hostname | IPv4address
 hostname      = *( domainlabel "." ) toplabel [ "." ]
 domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum
 toplabel      = alpha | alpha *( alphanum | "-" ) alphanum
 IPv4address   = 1*digit "." 1*digit "." 1*digit "." 1*digit
 port          = *digit

 path          = [ abs_path | opaque_part ]
 path_segments = segment *( "/" segment )
 segment       = *pchar *( ";" param )
 param         = *pchar
 pchar         = unreserved | escaped |
                 ":" | "@" | "&" | "=" | "+" | "$" | ","

 query         = *uric

 fragment      = *uric

 uric          = reserved | unreserved | escaped
 reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
                 "$" | ","
 unreserved    = alphanum | mark
 mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" |
                 "(" | ")"

 escaped       = "%" hex hex
 hex           = digit | "A" | "B" | "C" | "D" | "E" | "F" |
                         "a" | "b" | "c" | "d" | "e" | "f"

 alphanum      = alpha | digit
 alpha         = lowalpha | upalpha

 lowalpha      = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
                 "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
                 "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
 upalpha       = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
                 "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
                 "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
 digit         = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
                 "8" | "9"

では、http://www.studyinghttp.net:80/foo?bar#baz という URL を、その構文に従って解析していきましょう。

scheme (http)
リソースにアクセスするための手法を識別します。 http_URL の場合、schemehttp で確定です。
host (www.studyinghttp.net)
ホスト名、すなわちそのデータを持っているコンピュータの名前を指定します。 IP アドレスによる指定も可能ですが、FQDN による指定が推奨されます (RFC 1900 参照)。
port (80)
ポート番号。 サーバはポート番号別にサービスを振り分けて、通信を待ちうけます。 HTTP 通信の場合は通常 80 を使用しますが、それ以外のポート番号も使用できます。 ポート番号が明示されていない時は 80 を使用します。
abs_path (/foo)
絶対パス、すなわちそのコンピュータ内でのリソースの場所を指定します。 階層的な性質(ディレクトリ)を持つ URI では、/ を階層成分の区分に使います。
query (bar)
クエリ文字列。 絶対パスとの区切りには、? を使います。 指定したリソースに情報を渡す場合、例えば CGI にパラメータを渡す場合等に使います。
fragment (baz)
部分識別子。 絶対パスとの区切りには、# を使います。 RFC 3986 によれば、fragment も URI の中に含まれますが、依然として "http_URL" の中には fragment は含まれません。 HTTP において、fragment はリソース内の特定部分を指すものであり、即ち fragment はリソース取得後にのみ意味を持ちます。

HTTP URIの比較

RFC 2616のsection 3.2.3では、ある二つのURIを比較して「一致」しているかどうかを判定する際の注意点について記述されています。

二つの URI が一致しているかどうかを決めるために比較する時、クライアントは URI 全体で大文字・小文字を区別したオクテット同士の比較をすべきであるが、以下は例外とする。

"reserved" あるいは "unsafe" セット (RFC 2396 参照) 以外の全ての文字は、それらを ""%" HEX HEX" エンコーディングしたものと等しい。(※)

(※訳注) "unsafe" セットは、RFC 2396 中には存在しない。

例えば、以下の三つの URI は等価である。

 http://abc.com:80/~smith/home.html
 http://ABC.com/%7Esmith/home.html
 http://ABC.com:/%7esmith/home.html

先述のreserved及びunreserved以外の文字は、すべてパーセントエンコーディングされます。

HTTP URIの長さ

RFC 2616のsection 3.2.1では、HTTPにおけるURIの長さ(上限文字数)について記述されています。

HTTP プロトコルでは、URI の長さにどんな制限も設けていない。 サーバは、自身が持つどんなリソースの URI も扱えなければならないし、もしそのような URI を生成する GET ベースのフォームを用意するなら、無制限の長さの URI を扱えるべきである。 もし、その URI がサーバが処理できるものよりも長ければ、サーバは 414 (Request-URI Too Long) ステータスを返すべきである (section 10.4.15 参照)。

注: いくつかの古いクライアントやプロクシ実装は 255 バイトを超える長さを持つ URI を適切にサポートしていないかもしれないので、サーバはそのような URI に頼る場合は注意を払うべきである。

HTTP/1.1では、HTTP URIの長さに関して、仕様上は制限は設けられていません。 ただし、「255バイトを超える長さのURIが処理できるか」などといったことは、それぞれのアプリケーション依存となります。 サーバは、URIが長すぎて処理できないと判断した場合は414レスポンスを返します。

サーバが中間処理をするために想定している Request-URI より長いため、サーバはリクエストのサービスを拒否している。 このまれな状態は、クライアントが長いクエリ情報を伴った POST リクエストを GET リクエストに不適当に変換した時、クライアントがリダイレクションの URI "ブラックホール" (例えば、リダイレクトされた URI が自身の末尾を指すようなものを自身の前に置いてしまうような状態) に陥った時、あるいはサーバが Request-URI の読み出しや操作のために固定長バッファを使用しているいくつかのサーバに存在する当面のセキュリティホールを利用しようとしているクライアントからアタックを受けている時にのみ起こる傾向がある。

POSTメソッドでは、サーバに対する送信データをリクエストボディ部に含めますが、それに対しGETメソッドでは、送信データはURIに含まれます。 HTTPでデータをアップロードする状況を思い浮かべていただければわかるかと思いますが、リクエストボディ部には、1メガバイトでも、1ギガバイトでもデータを含めることができます。 しかし、そのような長いデータを誤ってURIに展開してしまった場合、サーバ側ではバッファオーバーフローのようなセキュリティリスクが発生する確率が極端に高まってしまうので、通常は上限値を超える長さのURIは受け付けないようになっています。

リクエストURI

リクエストを適用するリソースを指定するためのURIをリクエストURIと呼びます。 RFC 2616のsection 5.1.2をご覧ください。

Request-URI は、Uniform Resource Identifier (section 3.2) であり、リクエストを適用するリソースを識別する。

 Request-URI    = "*" | absoluteURI | abs_path | authority

Request-URI の四つのオプションは、そのリクエストの性質に依存する。

HTTP/1.1 では、リクエスト URI として 4 つのパターンが定義されています。

アスタリスク "*" は、そのリクエストが特定のリソースではなく、サーバ自身に適用するという事を意味し、使用されるメソッドがリソースに適用される必要がない時にのみ許される。 一例を挙げる。

 OPTIONS * HTTP/1.1

* というリクエスト URI は、OPTIONS というメソッドでのみ使用されます。 この URI は、特定のリソースではなく、サーバそのものを指定する時に使用します。

absoluteURI 形式は、リクエストがプロクシに対して生成されている時に要求される。 プロクシは、そのリクエストを転送するか、有効なキャッシュ内から提供する時に呼び出され、レスポンスを返す。 プロクシは、そのリクエストを別のプロクシか、あるいは absoluteURI によって特定されたサーバに直接送る事ができる事に注意せよ。 リクエストループを避けるために、プロクシはそのサーバ名をエイリアス、ローカルバリエーション、数値 IP アドレスまで含め、すべて理解できなければならないRequest-Line の例は以下の様になる。

 GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1

HTTP の将来のバージョンにおいてすべてのリクエストが absoluteURI へ移行する事ができるように、例え HTTP/1.1 クライアントはプロクシへのリクエストとしてのみしか生成しないものであったとしても、全ての HTTP/1.1 サーバはリクエストにおける absoluteURI 形式を受け入れなければならない

absoluteURI形式は、文字通り“絶対URI”、すなわち“http://”で始まる形式のURIです。 このタイプは、主にプロクシへのリクエスト時に使用されますが、将来のバージョンでabsoluteURI形式が使用されるかもしれないので、HTTP/1.1サーバはabsoluteURI形式を受け入れることができなければなりません。

authority 形式は、CONNECT メソッド (section 9.9) のみで使用する。

CONNECT メソッドは、プロクシにトンネル接続の確立を要求する。 リクエストラインの Request-URI の部分は、常に URI 一般構文 [2] によって定義されるような 'authority' であり、リクエストされるコネクションの目的地となるホスト名とポート番号とをコロンで区切ったものである。

 CONNECT server.example.com:80 HTTP/1.1
 Host: server.example.com:80

authority 形式は、CONNECT メソッドで使用されます。 CONNECT メソッドは、プロクシにトンネル接続の確立を要求するためのメソッドなので、指定する authority はリソースのある場所ではなく、トンネル接続をするサーバとなります。

Request-URI の最も一般的な形式は、オリジンサーバやゲートウェイ上のリソースを識別するために使用される事である。 この場合、URI の絶対パスは Request-URI として通信されなければならない (section 3.2.1, abs_path 参照) し、URI のネットワークロケーション(authority) は、Host ヘッダフィールドにおいて転送されなければならない。 例えば、オリジンサーバから直接上記のリソースを回収する事を望むクライアントは、ホスト "www.w3.org" のポート 80 に TCP 接続を確立し、その行を送る。

 GET /pub/WWW/TheProject.html HTTP/1.1
 Host: www.w3.org

残りのリクエストをその後に送る。 絶対パスは空ではない事に注意せよ。 もし、元の URI で何も与えられていなければ、それは "/" (サーバのルート) が与えられなければならない

Request-URI は、section 3.2.1 に記された形式で送られる。 もし、 Request-URI に "% HEX HEX" エンコード [42] が使用されていたら、オリジンサーバはそのリクエストを適切に解釈するためにその Request-URIをデコードしなければならない。 サーバは、不正な Request-URI には、適切なステータスコードをもって応答すべきである

クライアントがオリジンサーバに直接接続するような場合では、通常 リクエスト URI には abs_path、すなわち絶対パスを用います。 (但し、前述の通り、HTTP/1.1 サーバは absoluteURI、すなわち "http://" から始まる絶対 URI 形式も受け入れなければなりません。)

abs_path は、必ず / で始まります。 ユーザエージェントがユーザにリクエスト URI を入力させた時に、もし空の値を入力したとしても、ユーザエージェントは / を補いましょう。

パーセントエンコーディング

パーセントエンコーディングとは、ある文字を“%”と16進数字二つを用いて変換する処理のことを言います。 RFC 3986 の Section 2.1 をご覧下さい。

パーセントエンコーディング{percent-encoding} メカニズムは、オクテットの対応する文字が認められた文字の範囲外にある、あるいは構成要素の中で区切り子として使用されている場合に使用される。 パーセントエンコードされたオクテットは、パーセント文字 "%" と、そのオクテットの数値を表している二桁の 16 進数字から成る三重語としてエンコードされる。 例えば、"%20" は 2 進オクテット "00100000" (ABNF: %x20) についてのパーセントエンコーディングであり、US-ASCII のスペース文字 (SP) に対応している。 Section 2.4 は、パーセントエンコーディングとデコーディングが適応される時について記述している。

 pct-encoded = "%" HEXDIG HEXDIG

大文字の 16 進数字 'A' から 'F' は、小文字の 'a' から 'f' とそれぞれ等価である。 二つの URI のパーセントエンコードされたオクテット内で使用される 16 進数字の大文字・小文字のみが異なる場合、それらは等価である。 整合性を持たせるため、URI の生成を行うもの{producers} や正規化を行うもの{normalizers} は全てのパーセントエンコーディングについて大文字の 16 進数字を使用すべきである。

この "% HEXDIG HEXDIG" 形式のものは、これまで「URI(URL) エスケープ」とか「URI(URL) エンコード」等と呼ばれてきましたが、RFC 3986 では「パーセントエンコーディング」という言葉をもって定義されましたので、今後はこの言葉を用いるようにしましょう。

パーセントエンコーディングにおいて、16進数字の大文字と小文字は等価です。 例えば、“=”(等号)をパーセントエンコーディングすると、“%3D”あるいは“%3d”となりますが、これは等価となります。 ただし、整合性を持たせるために、例えばHTML文書内でパーセントエンコーディングを使用する場合は、大文字である“%3D”の方を利用しましょう。

URI 内で使用できる文字

URI 内で使用できる文字について、RFC 3986 の Section 2.2, 2.3 をご覧下さい。

URI は、"予約されている" 集合内の文字によって区切られる構成要素及び副構成要素を含んでいる。 これらの文字は、URI の逆参照アルゴリズムにおける一般的な構文、各スキーム特有の構文、あるいは実装特有の構文によって区切り子として定義される (あるいはされない) ので、"予約されている" と呼ばれる。 URI 構成要素についてのデータがデリミタとして予約されている文字の目的と競合する場合、競合するデータは URI が形成される前にパーセントエンコーディングされなければならない。

 reserved    = gen-delims / sub-delims

 gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

 sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
             / "*" / "+" / "," / ";" / "="

予約されている文字の目的は、URI 中の他のデータから区別可能である区切り文字の集合を提供する事である。 予約文字を、対応するパーセントエンコードされたオクテットに置き換えている点が異なる URI は、等価ではない。 ほとんどのアプリケーションにおいて、予約文字をパーセントエンコーディングする、あるいは予約文字に対応するパーセントエンコードされたオクテットをデコードする事によって、URI がどう解釈されるかが変わるであろう。 従って、予約されている集合内の文字は正規化{normalization} から保護されており、それ故に、それらは URI 内のデータ副構成要素を区切るためにスキーム特有、あるいは生成を行うもの特有のアルゴリズムによって使用されても安全であるだろう。

URI 内に含む事が認められており、予約目的のない文字は、予約されていない (unreserved) と呼ばれる。 これは、大文字と小文字のアルファベット、数字、ハイフン、ピリオド、アンダースコア、チルダが含まれる。

 unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

非予約文字を、対応するパーセントエンコードされた US-ASCII オクテットに置き換えている点が異なる URI は、等価である: それらは同じリソースを識別する。 しかし、URI 比較を行う実装が常に比較の前に正規化を行うわけではない (Section 6 参照)。 整合性を持たせるため、URI の生成を行うものは ALPHA (%41-%5A と %61-%7A), DIGIT (%30-%39), hyphen (%2D), period (%2E), underscore (%5F), tilde (%7E) の範囲におけるパーセントエンコードされたオクテットを生成すべきではないし、URI を発見した時に、URI 正規化によってそれらを対応する非予約文字にデコードすべきである。

RFC 3986 では、区切り子として用途が決まっている記号の集合を予約文字としました。 これに対し、それ以外の文字を非予約文字 (予約されていない文字)と呼ばれます。 たとえば、"=" (等号) は予約文字なので、(特に、クエリ部分で) URI として使用する場合には特にパーセントエンコードする必要がありますが、"~" (チルダ) は非予約文字なので、その必要がありません。

クエリ文字列の取り扱いによる危険性

Request-URI のクエリ文字列は、指定したリソースに情報を渡す場合に使いますが、この文字列は URI 中に表れるので、第三者が容易に閲覧可能なものになっています。 この文字列の不用意な取り扱いによる危険性について、section 15.1.3 に記述されています。

HTTP プロトコルを使うサービスの作者は、その Request-URI にエンコードされたデータが現れるので、機密性の高いデータの提出に GET を使ったフォームを使うべきではない。 多くの現存のサーバやプロクシ、ユーザエージェントは、第三者が見るかもしれない場所にその Request-URI を記録するだろう。 サーバは、代わりに POST を使ったフォームを使うべきである。

もしかしたら、例えば Web メール等、Web 中のあるサービスにログインしている場合に、クエリ中に ID やパスワードを含ませた URI があるかもしれません。 しかし、これはとても危険であるというはおわかりいただけると思います。 この場合、サービスの提供者は、POST メソッドによるフォームを用いた逐一の認証や、例えば状態維持が目的ならば HTTP Cookies 等を利用すべきです。

参照文献

Webリソース