カテゴリー
オライリーJavaScript

multipart/form-dataリクエスト

HTMLフォームにファイルアップロード要素のほかにも要素が含まれるときには、 ブラウザは通常のフォームエンコード方法を使うことができない このような場合は「multipart/form-data」として知られる特殊なコンテントタイプを使って フォームをPOSTしなければならない

カテゴリー
オライリーJavaScript

ファイルのアップロード

HTMLフォームの<input type="file">要素でユーザがファイルを選択したときに、 POSTリクエストのボディとしてファイルのコンテンツを送信する機能がある。

send()メソッドにFileオブジェクトを引数として渡すことで、ファイルをアップロードできる。 File()オブジェクトコンストラクタはない。 <input type="file">要素には、filesプロパティがある。 Fileオブジェクトの配列のようなオブジェクトが格納されている Fileオブジェクト(22.6、22.7節) ドラッグ&ドロップAPIでは、ユーザが要素にドロップしたファイルに、 dropイベントのdataTransfer.filesプロパティを使ってアクセスできる。 Fileタイプは、もっと汎用的なBlobタイプの派生型(22.5節、22.6.3項)

カテゴリー
オライリーJavaScript

XMLエンコードされたリクエスト

XMLドキュメント

<query>
    <find zipcode="02143" radius="1km">
        pizza
    </find>
</query>

XMLHttpRequestのsend()メソッドの引数に、XML Documentオブジェクトを渡すこともできる。

Content-Typeヘッダを指定せずに、send()メソッドに、 XML Documentオブジェクトを引数に渡すと、自動的に適切なヘッダを設定してくれる。

Content-Typeヘッダを指定せずに、send()メソッドに、 文字列を渡すと、自動的に適切な「text/plain:charset=utf-8」というヘッダを設定してくれる。

カテゴリー
オライリーJavaScript

JSONエンコードされたリクエスト

JSON.stringify()メソッド(6.9節)を使ってリクエストボディをエンコードする方法

カテゴリー
オライリーJavaScript

フォームエンコードされたリクエスト

ユーザがフォームを送信するとき、フォーム中のデータ(各フォーム要素の名前と値)は文字列形式にエンコードされ、 リクエストと一緒に送信される。 エンコードされたフォームデータはリクエストボディとして扱われる。

各フォーム要素の名前と値に対してURIエンコードする これを=でつなぎ、&で複数指定する。

find=pizza&zipcode=02134&radius=1km

上記は、以下のようなJavaScriptオブジェクトをフォームエンコードで表現したもの

{
    find: "pizza",
    zipcode: 02134,
    radius: "1km"
}

フォームデータエンコード形式のMIMEタイプ

application/x-www-form-urlencoded

フォームデータをPOSTするとき、Content-Typeには、この値を設定する必要がある。

encodeURIComponent()メソッド

HTMLフォームはデフォルトではPOSTリクエストを使うが、GETリクエストを使うこともできる。 フォーム送信により、読み出し専用の問い合わせを行いたいだけの場合は、GETのほうが適切。 GEETリクエストにはボディがない。 したがってエンコードされたデータ(ペイロード)は、URLの検索部(疑問符の後)としてサーバーに送信する。

カテゴリー
オライリーJavaScript

リクエストボディのエンコード

POSTリクエストのボディには、クライアントがサーバに渡そうとしているデータが含まれる

カテゴリー
オライリーJavaScript

レスポンスの解釈

18.1.2.1の例では、サーバがテキスト形式 (MIMEタイプ「text/plain」、「text/html」、「text/css」など)で レスポンスを送信すると想定していた。 このため、XMLHttpRequestオブジェクトのresponseTextプロパティからのレスポンスを取得していた。 しかし、サーバのレスポンスはほかの方法でも処理できる サーバがレスポンスをXMLドキュメントやXHTMLドキュメント形式で送信した場合 responseXMLプロパティからDocumentオブジェクト取得できる したがって、15章の方法を使って、検索したり、調べたりできる サーバからのレスポンスとして、オブジェクトや配列など、構造化されたデータを送信したい場合は、 データをJSON形式(6.9節)の文字列にエンコードすれば送信できる このようなデータを受け取ったときは、responseTextプロパティを JSON.parse()に渡す。 JSON形式 JSON.parse(responsText) スクリプトの実行 13.4節参照 バイナリ形式のレスポンスを処理する方法 Blob(22.6.2項) サーバのレスポンスを適切に解釈するには、MIMEタイプが正しく指定された 「Content-Type」ヘッダーをサーバが送信していなければならない overideMimeType()メソッド //レスポンスをXMLドキュメントとして処理しない

request.overrideMimeType("text/plain; charset=utf-8"); 

カテゴリー
オライリーJavaScript

同期レスポンス

open()メソッドの3番目の引数にfalseを指定すると、同期処理する send()メソッドは、リクエストが完了するまでブロックする。 この場合、イベントハンドラを使う必要はない。 send()が戻ってきたら、XMLHttpRequestオブジェクトの statusプロパティとresponseTextプロパティを確認すればよいだけです。

//指定したURLのコンテンツ用に、同期型の HTTP GETリクエストを発行する
//レスポンスのテキストを返す。
//リクエストが失敗した場合や、
//レスポンスがテキストでなかった場合は、エラーをスローする
function getTextSync(url) {
    var request = new XMLHTTPRequest();	//新しいリクエストを作成する
    request.open("GET", url, false);	//同期型にするために、falseを渡す
    request.send(null);	//ここでリクエストを送信する
    
    //レスポンスが200 OK 以外であればエラーをスローする
    if(request.status !== 200) throw new Error(request.statusText);
    
    //コンテンツタイプが異なる場合はエラーをスローする
    var type = request.getResponsHeader("Content-Type");
    if (type.match(/^text/)) 	//レスポンスがテキストであることを確認
        throw new Error("Expected textual response; got: " + type);
    
    return request.responseText;
}

クライアントサイドJavaScriptはシングルスレッドで動作するため、 send()の帰りを待っている間、ブラウザUIは、完全に停止するので、利用はさけるべき。

カテゴリー
オライリーJavaScript

レスポンスの読み出し

完全なHTTPレスポンスは以下の4つから構成される HTTPレスポンス ステータスコード レスポンスヘッダ レスポンスボディ XMLHttpRequestオブジェクトのプロパティやメソッドから取得できる statusプロパティ statusTextプロパティ HTTPのステータス(200:リクエスト成功、404:Not Foundなど) getResponseHeader()メソッド getAllResponsesHeaders()メソッド レスポンスヘッダを取得する ただし、クッキー関連のヘッダーはフィルタされている responseTextプロパティ レスポンスボディをテキスト形式で取得 responseXMLプロパティ Document形式で取得 send()メソッドはリクエストの尊信処理を開始したあと、すぐに戻ってくる。 たいてい、HTTPレスポンスは非同期で処理する。 上記のプロパティやメソッドは、レスポンスが届くまでは使えない。 レスポンスを受け取ったことを通知してもらうためには、 XMLHttpRequestオブジェクトのreadystatechange、progressイベントを受信する。 readyStateプロパティ 0 UNSET open()はまだされていない 1 OPEND open()が呼び出された 2 HEADRES_RECEIVED ヘッダを受け取った 3 LOADING レスポンスボディを受信中 4 DONE レスポンスの受信が完了した イベントハンドラでreadyStateステートの値を必ずチェックするようにする。 readystatechangeイベントを受信するには、 XMLHttpRequestオブジェクトのonreadystatechangeプロパティに、イベントハンドラ関数を設定する。

カテゴリー
オライリーJavaScript

リクエストの指定

XMLHttpRequestオブジェクトを生成した後、次にすることをは、 XMLHttpRequestオブジェクトのopen()メソッドを呼び出す。 request.open("GET", //GETリクエストを開始する "data.csv"); //このURLのコンテンツを取得するため open()メソッドの1番目の引数には、HTTPメソッドを指定する。 HTTPプロトコルと一致するように、大文字で指定するのが普通。 GETメソッド URLでリクエストするリソースをすべて表せて、リクエストによりサーバ側に副作用がなく、 サーバのレスポンスがキャッシュ可能であればGETリクエストが適切 POSTメソッド HTMLフォームで使われるのが普通 リクエストボディに追加データ(フォームデータ)が含まれる。 このデータは普通はサーバ上のデータベースに格納される。 これが副作用。 同じURLに対して繰り返しPOSTリクエストを送信したときに、サーバのレスポンスが異なる場合もある。 また、POSTメソッドを使ったリクエストはキャッシュされない。 DELETE、HEAD、OPTIONS、PUTメソッドも使える。 CONNECT、TRACE、TRACKメソッドは、セキュリティ上の問題により、明示的に禁止されている。 open()メソッドの2番目の引数には、リクエストの送信先となるURLを指定する。 相対URLを指定した場合は、open()メソッドを呼び出したスクリプトを含むドキュメントからの相対位置になる。 同一出身ポリシー リクエストヘッダの設定 POSTリクエストでは、Content-Typeを指定して、リクエストボディのMIMEタイプを指定する必要がある。 request.setRequestHeader("Content-Type", "text/plain"); Content-Length,Date,Referer,User-Agentヘッダなどは、設定不可 ユーザ名とパスワードで保護されたURLをリクエストする場合は、open()メソッドの4番目と5番目の引数として指定する リクエストボディの設定 サーバーにリクエストを送信する。 request.send(null); GETリクエストはボディを持たないので、引数としてnullまたは省略する。 POSTリクエストはボディを持つ。 setRequestHeader()で指定した、Content-Typeと一致するボディを引数として指定する。 send()メソッドはリクエストの尊信処理を開始したあと、すぐに戻ってくる。 たいてい、HTTPレスポンスは非同期で処理する。