【メモ】『js権威ガイド』-第18章スクリプト化HTTP-18.1 XHR使用(1)


1.Ajaxでクライアントがサービス側からデータを要求し、Conetでサーバ側からクライアントにデータを送信する.
2.XMLHttpRequestを使用:
(1).指定要求:request.open
第1のパラメータは動作を表し、共通値はPOSTとGETであり、GETはURLに適用されて要求リソースを完全に指定し、要求はサーバに副作用がなく、サーバの応答はキャッシュ可能である.POSTは、サーバのデータベースに格納される可能性のある追加のデータを要求に含めるフォームによく使用されます.応答が得られるたびに異なる可能性があるため、この方法を用いた応答をキャッシュすべきではない.
2番目のパラメータはURLで、彼は要求の主体で、このurlは相対的なドキュメントのurlで、絶対urlを使用する場合、ドメイン間要求を許可しない前提の下で、所在するドキュメントの対応する内容に一致しなければならない.
要求ヘッダの設定:
request.setRequestHeader("Content-TYpe", "text/plain");
(2).送信要求,
パラメータはオプションのボディであり、GET要求であればnullを送信するか、パラメータを設定しない.POSTリクエストの場合はリクエストヘッダを使用してContent-Typeを指定する必要があります
function postMessage(msg) {
    var request = new XMLHttpRequest();
    request.open("POST", "/log.php");
    request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
    request.send(msg);
};

(3).応答を取得する:
a.ステータスコードは、statusとstatusTextによってデジタルまたはテキストの形式で返され、例えば200は成功を表し、404はサーバ上のリソースに一致しないことを表す.
b.getResponseHeader(headName)およびgetAllResponseHeaders()メソッドを使用して、応答ヘッダを問い合わせることができる.
c.応答主体はresponseText属性からテキスト形式を得ることができる.resposneXMLからDocument形式を得る.
d.デフォルトの応答は非同期応答であるため、readystatechangeイベントをリスニングしてreadystaeをチェックすることによって要求が応答されたか否かを判断し、応答主体を得る必要がある
e.同期応答:
Open関数の3番目のパラメータがfalseで同期要求を表すように設定すると、sendメソッドは要求が完了するまでブロックされます.これはreadyStateを判断する必要はありません.
f.解析応答主体:
function getText(url, callback) {
	var request = new XMLHttpRequest();
	request.open("GET", url);
	request.onreadystatchange = function() {
		if (request.readyState === 4 && request.status === 200) {
			var type = request.getResponseHeader("Content-Type");
			// if (type.match(/^text/))
				// callback(request.responseText);
			if (type.indexOf("xml") !== -1 && request.responseXML)
				callback(request.responseXML);
			else if (type === "application/json")
			    callback(JSON.parse(request.responseText));
			else 
				callback(request.responseText);
		}
	};
	request.send(null);
};
はrequest.overrideMimeType(mimeType)を使用することができる.変換解析方式の指定
(4).作成要求主体:
a.POST動作で要求ヘッダを設定するContent-typeタイプがアプリケーション/x-www-form-urlencodedであれば、name=value&形式の文字列を要求主体とすることができる.
function encodeFormData(data) {
	if (!data) return "";
	var pairs = [];
	for (var name in data) {
		if (!data.hasOwnProperty(name)) continue;
		if (typeof data[name] === "function") continue;
		var value = data[name].toString();
		name = encodeURIComponent(name.replace("%20", "+"));
		value = encodeURIComponent(value.replace("%20", "+"));
		pairs.push(name + "=" + value);
		return pairs.join("&");
	}
};

request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send(encodeFormData(data));

b.JSON.stringifyを使用する.
c.XMLドキュメントを使用する:
var doc = document.implementation.createDocument("", "root", null);
var root = doc.documentElement;
var find = doc.createElement("tag");
root.appendChild(find);
find.setAttribute("attri1", value);
find.appendChild(doc.createTextNode(what));
request.send(doc);

d.ファイルのアップロード:
ファイルはBlobバイナリ・オブジェクトのサブクラスに属し、XHR 2は任意のBlobオブジェクトへの転送を許可します.Content-Type値を設定する場合は、Blobオブジェクトのtypeプロパティを使用します.
var elts = document.getElementsByTagName("input");
for (var i = 0; i < elts.length; i++) {
	var input = elts[i];
	if (input.type !== "file") continue;
	var url = input.getAttribute("data-uploadto");
	if (!url) continue;
	input.addEventListener("change", function() {
		var file = this.files[0];
		if (!file) return;
		var xhr = new XMLRequest();
		xhr.open("POST", url);
		xhr.send(file);
	}, false);
}

e.FormDataを使用して混合種類の要求を生成する:
function postFormData(url, data, callback) {
	if (typeof FormData === "undefined")
		throw new Error("FormData is nor implemented");
	var request = new XMLHttpRequest();
	request.setRequestHeader("Content-Type", "multipart/form-data");
	request.onreadystatechange = function() {
		if (request.readyState === 4 && callback) {
			callback(request);
		}
	};
	var formdata = new FormData();
	for (var name in data) {
		if (!data.hasOwnProperty(name)) continue;
		var value = data[name];
		if (typeof value === "function") continue;
		formdata.append(name, value);
	}
	request.send(formData);
};