1. ホーム
  2. Web制作
  3. HTML/Xhtml

HTMLデータ投稿_Power Node Java Academy仕上げ

2022-01-08 02:19:22

HTTP/1.1 プロトコルで規定されている HTTP リクエストメソッドは、OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT です。一般的にPOSTはサーバにデータを送信するために使用され、この記事ではPOSTによるデータ送信のいくつかの方法について説明します。

ご存知のように、HTTPプロトコルはTCP/IPプロトコルの上に構築された、アスキーによるアプリケーション層の仕様です。この仕様では、HTTPリクエストをステータスライン、リクエストヘッダ、メッセージボディの3つのパートに分割しています。次のようなものだ。

<method> <request-url> <version>
<headers>
<entity-body></entity-body></headers></version></request-url></method>

プロトコルでは、POSTで送信するデータはメッセージボディ(entity-body)に入れる必要があると規定されていますが、データにどのようなエンコーディングを使わなければならないかは規定されていません。実際、最終的に送信される HTTP リクエストが上記の形式を満たす限り、メッセージボディの形式を決定するのは完全に開発者側に任されています。

ただし、データはサーバーで正常にパースされるまで送信されません。Javaなどの一般的なサーバーサイド言語やそのフレームワークには、一般的なデータ形式を自動的にパースする機能が組み込まれています。サーバーサイドは通常、リクエストヘッダのContent-Typeフィールドを頼りに、リクエストのメッセージボディがどのようにエンコードされているかを知り、ボディをパースするのです。ですから、POST送信のデータスキームに関しては、Content-Typeとメッセージボディの両方のエンコーディングメソッドを含んでいます。ここでは、それらについて正式に紹介します。

application/x-www-form-urlencoded

これはおそらく、POSTでデータを送信する最も一般的な方法です。ブラウザのネイティブフォームのenctype属性が設定されていない場合、application/x-www-form-urlencodedとしてデータを送信することになります。リクエストは以下のようになります(この記事では余計なリクエストヘッダは省略しています)。

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8
title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

次に、送信されたデータは key1=val1&key2=val2 のようにエンコードされ、key と val の両方が URL 転送されるように指定されます。ほとんどのサーバーサイドの言語では、この方法をうまくサポートしています。例えば、PHPでは、POST[′title′]はタイトルの値を取得し、_POST['sub']はサブ配列の値を取得します。

Ajaxでデータを送信するときに使うことが多い。例えば、JQueryのAjaxでは、Content-Typeのデフォルト値は"application/x-www-form-urlencoded;charset=utf-8"になっています。

multipart/form-data

これも一般的なPOSTデータ送信の方法です。フォームを使ってファイルをアップロードする場合、フォームのenctypedをこの値と等しくする必要があります。リクエストの例を直接見てみると

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

この例は少し複雑です。まず、異なるフィールドを分割するための境界が生成されます。境界は、ボディのコンテンツと重複しないように長く複雑なものになっています。それからContent-Typeは、データがmutipart/form-dataでエンコードされていることと、このリクエストのための境界が何であるかを指定します。メッセージボディは、フィールドの数に応じて同様に構成されたいくつかの部分に分けられ、それぞれが-boundaryで始まり、DeepLコンテンツ、キャリッジリターン、そして最後にフィールドの仕様(テキストまたはバイナリ)が続く。転送物がファイルの場合、ファイル名とファイルタイプ情報も含まれる。メッセージボディは-boundary--マーカーで終了する。mutipart/form-dataの詳細な定義については、rfc1867を参照してください。

この方法は、一般的にファイルのアップロードに使用され、主要なサーバーサイド言語によって十分にサポートされています。

上記の2つのPOSTデータ送信方法は、いずれもブラウザがネイティブにサポートしており、現段階ではネイティブフォームのフォームにのみ対応しています。しかし、より多くの Web サイト、特に WebApps がデータのやり取りに Ajax を使用するようになると、開発者にとってより便利な新しいデータ送信方法を定義することが可能になります。

アプリケーション/json

application/json このContent-Typeは、確かにレスポンスヘッダとしては目新しいものではありません。実際、メッセージのボディがシリアライズされた JSON 文字列であることをサーバーに伝えるためのリクエストヘッダとして、このヘッダが使われることが多くなっています。JSON仕様の普及により、低バージョンのIEを除く主要ブラウザはJSON.stringifyをネイティブサポートしており、サーバサイド言語にもJSONを扱う関数があるので、JSONを使うのに困ることはないでしょう。

また、JSONフォーマットは、Key-Valueペアよりもはるかに複雑な構造化データをサポートしている点も便利です。数年前、非常に深いレベルのデータを提出しなければならないプロジェクトに携わったとき、データをJSON化してから提出したのを覚えています。しかし、その時はJSONの文字列をvalとして、やはりkey-valueペアで、x-www-form-urlencodedで送信していたのです。

GoogleのAngularJSのAjax機能は、デフォルトでは、JSON文字列を送信します。例えば、以下のようなコードです。

var data = {'title':'test', 'sub' : [1,2,3]};
$http.post(url, data).success(function(result) {
...
});

最終的に送信されたリクエストは

POST http://www.example.com HTTP/1.1
Content-Type: application/json;charset=utf-8
{"title":"test","sub":[1,2,3]}

複雑な構造のデータも簡単に送信できるこの方式は、特にRESTfulなインターフェースに適しています。Chrome自身の開発ツールやFirebug、Fiddlerなどの主要なパケット取得ツールは、いずれもJSONデータをツリー構造で表示するので、非常に使い勝手が良い。ただし、phpなど、まだこの方法に対応していないサーバーサイドの言語もあり、その場合は上記のリクエストから$_POSTオブジェクト経由でコンテンツを取得することができません。リクエストヘッダの Content-Type が application/json の場合は、 php://input から生の入力ストリームを取得して json_decode でオブジェクトに変換します。いくつかの Java フレームワークでは、すでにこれを実行しています。

もちろん、AngularJSはx-www-form-urlencodedを使ってデータを送信するように設定することも可能です。

テキスト/xml

XML-RPC (XML Remote Procedure Call). It is a remote call specification that uses HTTP as the transport protocol and XML as the encoding method. A typical XML-RPC request looks like this.
POST http://www.example.com HTTP/1.1
Content-Type: text/xml
<! --?xml version="1.0"? -->
<methodcall>
<methodname>examples.getStateName</methodname>
<params>
<param>
<value><i4>41</i4></value>
</params>
</methodcall>

XML-RPCプロトコルは、シンプルで機能的であり、様々な言語で実装されています。また、WordPressのXML-RPC Apiや検索エンジンのpingサービスなど、広く利用されている。JavaScriptでも、このようなデータのやりとりをサポートするライブラリが公開されており、既存のXML-RPCサービスにも十分対応できています。しかし、個人的にはXMLの構造は肥大化しすぎており、一般的なシナリオではJSONの方が柔軟で便利だと感じています。