web-dev-qa-db-ja.com

HTTPでパラメータはどここのように送信されますか POST 要求?

HTTP _ get _ リクエストでは、パラメータは クエリ文字列 として送信されます。

http://example.com/page?parameter = value&also = another

HTTP _ post _ リクエストでは、パラメータはURIとともに送信されません。

値はどこにありますか? リクエストヘッダでは?リクエスト本体では?それはどのように見えますか?

1314
Camilo Martin

値は、コンテンツタイプで指定されている形式で、要求本文で送信されます。

通常、コンテンツタイプはapplication/x-www-form-urlencodedなので、リクエストボディはクエリ文字列と同じ形式を使用します。

parameter=value&also=another

フォームでファイルのアップロードを使用するときは、代わりにmultipart/form-dataエンコーディングを使用します。これは形式が異なります。それはもっと複雑ですが、あなたは通常それがどのように見えるかを気にする必要はないので私は例を示しませんが、それが存在することを知るのは良いことです。

1109
Guffa

コンテンツは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要求と応答ペイロードがネットワーク経由で送信されているのを確認できます。

397
Joe Alfano

短い回答: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( 関連するRFCセクション

GETリクエストを実行するとき、サーバーに1つまたは一連のエンティティを要求します。クライアントが結果をフィルタリングできるようにするには、URLのいわゆる「クエリ文字列」を使用できます。クエリ文字列は、?の後の部分です。これは RI構文 の一部です。

そのため、アプリケーションコード([receives request)の部分)の観点から、これらの値にアクセスするにはURIクエリパーツを調べる必要があります。

キーと値はURIの一部であることに注意してください。ブラウザmay URIの長さに制限を課します。 HTTP標準では、制限はありません。しかし、これを書いている時点では、ほとんどのブラウザーdoはURIを制限しています(特定の値はありません)。 GET要求は、サーバーに新しい情報を送信するためにneverを使用する必要があります。特に大きな文書ではありません。そこでPOSTまたはPUTを使用する必要があります。

POST( 関連するRFCセクション

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-urlencodedmultipart/form-dataまたはapplication/jsonなど)との間でメッセージ本文をデコード/エンコードする方法を提供します。それは簡単です。カスタムタイプには、潜在的にもう少し作業が必要です。

標準のHTMLフォームでエンコードされたドキュメントを例として使用して、アプリケーションは次の手順を実行する必要があります。

  1. Content-Typeフィールドを読む
  2. 値がサポートされているメディアタイプのいずれでもない場合は、415ステータスコードで応答を返します
  3. それ以外の場合は、メッセージ本文から値をデコードします。

繰り返しますが、PHPなどの言語、または他の一般的な言語のWebフレームワークがおそらくこれを処理します。例外は415エラーです。アプリケーションがサポートするか、サポートしないかを選択するコンテンツタイプを予測できるフレームワークはありません。これはあなた次第です。

PUT( 関連するRFCセクション

PUTリクエストは、POSTリクエストとまったく同じ方法で処理されます。大きな違いは、POSTリクエストにより、サーバーが新しいリソースを作成する方法を決定できるようにすることです。歴史的に(現在廃止されているRFC2616から、要求が送信されたURIの「従属」(子)として新しいリソースを作成することでした)。

対照的にPUTリクエストは、リソースを正確に「デポジット」することになっていますatそのURI、およびexactlyそのコンテンツ。これ以上でもそれ以下でもありません。アイデアは、clientcompleteリソースを「PUT」する前に作成することです。サーバーは、指定されたURLでas-isを受け入れる必要があります。

結果として、POSTリクエストは通常​​、既存のリソースをreplaceに使用しません。 PUTリクエストでは、作成およびの両方の置換を実行できます。

サイドノート

また、追加データをリモートに送信するために使用できる「 path parameters 」もありますが、あまり一般的ではないため、ここでは詳しく説明しません。ただし、参照用に、RFCからの抜粋を次に示します。

階層パスのドットセグメントは別として、パスセグメントは一般的な構文では不透明と見なされます。 URI生成アプリケーションは、多くの場合、セグメントで許可されている予約文字を使用して、スキーム固有またはデリファレンスハンドラ固有のサブコンポーネントを区切ります。たとえば、セミコロン( ";")およびイコール( "=")予約文字は、多くの場合、そのセグメントに適用可能なパラメーターとパラメーター値を区切るために使用されます。コンマ( "、")予約文字は、同様の目的でよく使用されます。たとえば、あるURIプロデューサーは「name; v = 1.1」などのセグメントを使用して「name」のバージョン1.1への参照を示し、別のURIプロデューサーは「name、1.1」などのセグメントを使用して同じことを示します。パラメータタイプはスキーム固有のセマンティクスによって定義されますが、ほとんどの場合、パラメータの構文はURI参照解除アルゴリズムの実装に固有です。

344
exhuma

ブラウザの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

投稿値になります。

54
zurfyx

POST要求のデフォルトのメディアタイプはapplication/x-www-form-urlencodedです。これは、キーと値のペアをエンコードするための形式です。キーは重複する可能性があります。各キーと値のペアは&文字で区切られ、各キーはその値と=文字で区切られています。

例えば:

Name: John Smith
Grade: 19

次のようにエンコードされています。

Name=John+Smith&Grade=19

これはHTTPヘッダの後のリクエストボディに配置されます。

20
Nejat

一部の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(改行)です。

17

HTTP POSTのフォーム値は、クエリ文字列と同じ形式で、要求本文で送信されます。

詳しくは spec を参照してください。

13
SLaks