HTTP _ get _ リクエストでは、パラメータは クエリ文字列 として送信されます。
http://example.com/page?parameter = value&also = another
HTTP _ post _ リクエストでは、パラメータはURIとともに送信されません。
値はどこにありますか? リクエストヘッダでは?リクエスト本体では?それはどのように見えますか?
値は、コンテンツタイプで指定されている形式で、要求本文で送信されます。
通常、コンテンツタイプはapplication/x-www-form-urlencoded
なので、リクエストボディはクエリ文字列と同じ形式を使用します。
parameter=value&also=another
フォームでファイルのアップロードを使用するときは、代わりにmultipart/form-data
エンコーディングを使用します。これは形式が異なります。それはもっと複雑ですが、あなたは通常それがどのように見えるかを気にする必要はないので私は例を示しませんが、それが存在することを知るのは良いことです。
コンテンツはHTTPヘッダーの後に置かれます。 HTTP POSTのフォーマットは、HTTPヘッダーとそれに続く空白行、それに続く要求本文を持つことです。 POST変数は、キーと値のペアとして本体に格納されています。
これは、以下に示すHTTP Postの生のコンテンツで見ることができます。
POST /path/script.cgi HTTP/1.0
From: [email protected]
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
home=Cosby&favorite+flavor=flies
これは Fiddler のようなツールを使用して確認できます。これを使用すると、生のHTTP要求と応答ペイロードがネットワーク経由で送信されているのを確認できます。
短い回答:POSTリクエストでは、リクエストの「ボディ」で値が送信されます。 Webフォームでは、application/x-www-form-urlencoded
またはmultipart/form-data
のメディアタイプで送信される可能性があります。 Webリクエストを処理するように設計されたプログラミング言語またはフレームワークは、通常、そのようなリクエストで「The Right Thing™」を行い、すぐにデコードされた値(PHPの$_REQUEST
または$_POST
、またはPythonのcgi.FieldStorage()
、flask.request.form
)。
それでは、違いを少し理解しましょう。違いを理解するのに役立つかもしれません;)
GET
リクエストとPOST
リクエストの違いは主にセマンティックです。また、「使用」方法も異なります。これは、値の受け渡し方法の違いを説明しています。
GET
リクエストを実行するとき、サーバーに1つまたは一連のエンティティを要求します。クライアントが結果をフィルタリングできるようにするには、URLのいわゆる「クエリ文字列」を使用できます。クエリ文字列は、?
の後の部分です。これは RI構文 の一部です。
そのため、アプリケーションコード([receives request)の部分)の観点から、これらの値にアクセスするにはURIクエリパーツを調べる必要があります。
キーと値はURIの一部であることに注意してください。ブラウザmay URIの長さに制限を課します。 HTTP標準では、制限はありません。しかし、これを書いている時点では、ほとんどのブラウザーdoはURIを制限しています(特定の値はありません)。 GET
要求は、サーバーに新しい情報を送信するためにneverを使用する必要があります。特に大きな文書ではありません。そこでPOST
またはPUT
を使用する必要があります。
POST
リクエストを実行するとき、クライアントは実際にリモートホストに新しいdocumentを送信しています。したがって、query文字列は(意味的に)意味をなしません。これが、アプリケーションコードでそれらにアクセスできない理由です。
POST
はもう少し複雑です(そしてwayより柔軟です):
POSTリクエストを受信するときは、常に「ペイロード」、またはHTTPの用語で メッセージ本文 を期待する必要があります。 standard(私が知る限り。application/ octet-stream?かもしれません)形式がないため、メッセージ本文自体はほとんど役に立ちません。本文の形式は、Content-Type
ヘッダーで定義されます。 HTML FORM
要素をmethod="POST"
で使用する場合、これは通常application/x-www-form-urlencoded
です。もう1つの非常に一般的なタイプは、ファイルアップロードを使用する場合の multipart/form-data です。しかし、それはanythingであり、text/plain
からapplication/json
まで、またはカスタムapplication/octet-stream
の範囲です。
いずれの場合でも、POST
リクエストがアプリケーションで処理できないContent-Type
で作成された場合、 415
status-code を返す必要があります。
ほとんどのプログラミング言語(および/またはWebフレームワーク)は、最も一般的なタイプ(application/x-www-form-urlencoded
、multipart/form-data
またはapplication/json
など)との間でメッセージ本文をデコード/エンコードする方法を提供します。それは簡単です。カスタムタイプには、潜在的にもう少し作業が必要です。
標準のHTMLフォームでエンコードされたドキュメントを例として使用して、アプリケーションは次の手順を実行する必要があります。
Content-Type
フィールドを読む415
ステータスコードで応答を返します繰り返しますが、PHPなどの言語、または他の一般的な言語のWebフレームワークがおそらくこれを処理します。例外は415
エラーです。アプリケーションがサポートするか、サポートしないかを選択するコンテンツタイプを予測できるフレームワークはありません。これはあなた次第です。
PUT
リクエストは、POST
リクエストとまったく同じ方法で処理されます。大きな違いは、POST
リクエストにより、サーバーが新しいリソースを作成する方法を決定できるようにすることです。歴史的に(現在廃止されているRFC2616から、要求が送信されたURIの「従属」(子)として新しいリソースを作成することでした)。
対照的にPUT
リクエストは、リソースを正確に「デポジット」することになっていますatそのURI、およびexactlyそのコンテンツ。これ以上でもそれ以下でもありません。アイデアは、clientがcompleteリソースを「PUT」する前に作成することです。サーバーは、指定されたURLでas-isを受け入れる必要があります。
結果として、POST
リクエストは通常、既存のリソースをreplaceに使用しません。 PUT
リクエストでは、作成およびの両方の置換を実行できます。
また、追加データをリモートに送信するために使用できる「 path parameters 」もありますが、あまり一般的ではないため、ここでは詳しく説明しません。ただし、参照用に、RFCからの抜粋を次に示します。
階層パスのドットセグメントは別として、パスセグメントは一般的な構文では不透明と見なされます。 URI生成アプリケーションは、多くの場合、セグメントで許可されている予約文字を使用して、スキーム固有またはデリファレンスハンドラ固有のサブコンポーネントを区切ります。たとえば、セミコロン( ";")およびイコール( "=")予約文字は、多くの場合、そのセグメントに適用可能なパラメーターとパラメーター値を区切るために使用されます。コンマ( "、")予約文字は、同様の目的でよく使用されます。たとえば、あるURIプロデューサーは「name; v = 1.1」などのセグメントを使用して「name」のバージョン1.1への参照を示し、別のURIプロデューサーは「name、1.1」などのセグメントを使用して同じことを示します。パラメータタイプはスキーム固有のセマンティクスによって定義されますが、ほとんどの場合、パラメータの構文はURI参照解除アルゴリズムの実装に固有です。
ブラウザのURLバーに直接入力することはできません。
たとえば、POSTデータがインターネット上で Live HTTP Headers を使用して送信されている様子を確認できます。結果はそのようなものになります
http://127.0.0.1/pass.php
POST /pass.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://127.0.0.1/pass.php
Cookie: passx=87e8af376bc9d9bfec2c7c0193e6af70; PHPSESSID=l9hk7mfh0ppqecg8gialak6gt5
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
username=zurfyx&pass=password
それが言うところ
Content-Length: 30
username=zurfyx&pass=password
投稿値になります。
POST要求のデフォルトのメディアタイプはapplication/x-www-form-urlencoded
です。これは、キーと値のペアをエンコードするための形式です。キーは重複する可能性があります。各キーと値のペアは&
文字で区切られ、各キーはその値と=
文字で区切られています。
例えば:
Name: John Smith
Grade: 19
次のようにエンコードされています。
Name=John+Smith&Grade=19
これはHTTPヘッダの後のリクエストボディに配置されます。
一部のWebサービスでは、リクエスト data および metadata を別々に配置する必要があります。たとえば、リモート関数は、署名されたメタデータ文字列がURIに含まれているのに対して、データはHTTPボディに投稿されていると想定する場合があります。
POSTリクエストは意味的には次のようになります。
POST /?AuthId=YOURKEY&Action=WebServiceAction&Signature=rcLXfkPldrYm04 HTTP/1.1
Content-Type: text/tab-separated-values; charset=iso-8859-1
Content-Length: []
Host: webservices.domain.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)
name id
John G12N
Sarah J87M
Bob N33Y
このアプローチは、Webサーバーの「構文解析命令」である単一のContent-Type
を使用して、QueryStringとBody-Postを論理的に組み合わせたものです。
注意してください: HTTP/1.1は 折り返された 左側の#32
(スペース)と右側の#10
(改行)です。
HTTP POSTのフォーム値は、クエリ文字列と同じ形式で、要求本文で送信されます。
詳しくは spec を参照してください。