【社内勉強会】Ajaxの基礎(2017/10/18)
0. はじめに
内容
- Ajaxの基礎。
XMLHttpRequest
(ライブラリを使わずに)で理解する。
前提知識
- JavaScriptの基本的な構文を理解している人
- 配列
- オブジェクト
- イベント
- コールバック関数
注意
ここで紹介したXMLHttpRequestの使い方は、サンプル用で実務には適していません。以下の内容を考慮していません。
- エラー処理
- URLエンコード
参考図書
『改訂新版JavaScript本格入門』技術評論社
2016年発売で、ES2015に対応。
目次
-
XMLHttpRequest
でAjax - ライブラリでAjax
- JSONとAjax
1. XMLHttpRequest
でAjax
Ajaxとは
Asynchronous JavaScript + XMLの略。
JavaScript(XMLHttpRequestオブジェクト)を利用してサーバ側と非同期通信を行い、受け取った結果をDOM経由でページに反映するしくみ
※ 『JavaScript本格入門』P389 引用
従来型のWebアプリとAjaxアプリの比較した画像
※Ajax - Wikipedia 引用
従来型のWebアプリ
JSPで動作を確認する。
二乗した結果を表示する画面。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String strInput = request.getParameter("input");
String strOutput = "";
if (strInput != null) {
try {
Integer input = Integer.valueOf(strInput);
Thread.sleep(1000);
strOutput = String.valueOf(input * input);
} catch(Exception e) {}
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<form action="/SampleWeb/form.jsp" method="POST">
INPUT: <input name="input" type="text">
OUTPUT: <input name="output" type="text" value="<%=strOutput%>">
<input type="submit">
</form>
</body>
</html>
従来型のWebアプリの特徴
- 結果を表示する際に、ページ全体が書き換えられる
- 常にぺージ全体をリフレッシュする必要がある
- トラフィック量に無駄がある
- サーバと通信している間、クライアント側は操作できない
Ajaxアプリ
Ajax通信で結果を表示するためのServletを用意する。
/**
* クエリパラメタ"input"の値の二乗した結果を出力
*/
@WebServlet("/pow")
public class PowServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String strInput = request.getParameter("input");
String strOutput = "";
if (strInput != null) {
try {
Integer input = Integer.valueOf(strInput);
//数秒待つ
Thread.sleep(1000);
strOutput = String.valueOf(input * input);
} catch(Exception e) {}
}
PrintWriter out = response.getWriter();
out.println(strOutput);
}
}
XMLHttpRequestで非同期通信を実施
/**
* Calculateボタンを押したときの処理
*/
function calculate() {
const xhr = new XMLHttpRequest();
//リクエストが成功したときのイベントを設定
xhr.addEventListener("load", function() {
const output = xhr.responseText; //二乗の結果
//テキストボックスに表示
document.getElementById("output").value = output;
} ,false);
const url = "/SampleWeb/pow?input=" + document.getElementById("input").value;
//リクエストの初期化(GETで非同期通信)
xhr.open("GET", url, true );
//リクエストの送信
xhr.send(null);
//以下のデバグ文がいつ実行されるか確認
console.log("after");
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="sample.js"></script>
</head>
<body>
INPUT: <input id="input" name="input" type="text">
OUTPUT: <input id="output" name="output" type="text" value="">
<button onclick="calculate();">Calculate</button>
</body>
</html>
Ajaxアプリの特徴
- テキストボックスのみ更新される
- 画面のチラツキが解消
- サーバ通信中もクライアント側で処理を継続できる
- サーバ通信中に、コンソールに"after"が出力されることを確認
XMLHttpRequestで同期通信を実施
XMLHttpRequest.open
の3番目の引数にfalse
を指定する。
function calculate() {
//省略
//リクエストの初期化(GETで同期通信)
xhr.open("GET", url, false );
//リクエストの送信
xhr.send(null);
//以下のデバグ文がいつ実行されるか確認
console.log("after");
}
- 同期通信では、サーバ通信の完了後にコンソールに"after"が出力される。
XMLHttpRequestでPOSTを送信
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//doGetと同じ処理
//...
}
function calculate_POST() {
const xhr = new XMLHttpRequest();
//リクエストが成功したときのイベントを設定
xhr.addEventListener("load", function() {
const output = xhr.responseText; //二乗の結果
//テキストボックスに表示
document.getElementById("output").value = output;
} ,false);
//リクエストの初期化
xhr.open("POST", "/SampleWeb/pow", true );
//リクエストヘッダの指定
xhr.setRequestHeader("content-type","application/x-www-form-urlencoded;charset=UTF-8");
//リクエストの送信
xhr.send("input=" + document.getElementById("input").value);
}
-
XMLHttpRequest.open
メソッドに"POST"を指定 - リクエストヘッダに
Content-Type
を指定 -
XMLHttpRequest.open
メソッドにリクエストボディ(パラメータ)を指定
2. ライブラリでAjax
jQuery3のajax
メソッドを利用する
function calculate_jQuery() {
const data = {
input: document.getElementById("input").value
};
$.ajax({
type: "GET",
url: "/SampleWeb/pow",
data: data
}).done(function( data, textStatus, jqXHR){ //成功した場合
document.getElementById("output").value = data;
}).fail(function(jqXHR, textStatus, errorThrown){ //失敗した場合
console.log("error", jqXHR);
});
}
- オブジェクトを渡せる(
key=value
形式でない) - 成功した場合の処理は
done
、失敗した場合はfail
メソッドを使う
[補足] jQuery3からの場合
昔よく使われたsuccess、error、completeメソッドは、jQuery3から廃止された。
//昔の書き方
$.ajax({
url: "http://jsrun.it/assets/E/H/Z/t/EHZt3",
success: function (data) {
$("#results").append(data);
},
error: function () {
alert("読み込み失敗");
}
});
[補足] Fetch API
XMLHttpRequest
に替わる新しい機能。
https://developer.mozilla.org/ja/docs/Web/API/Fetch_API
https://qiita.com/tomoyukilabs/items/9b464c53450acc0b9574
[補足] Super Agent
Ajax専用ライブラリ。
https://github.com/visionmedia/superagent
2017年現在、jQueryは使われなくなりつつある
- JavaScriptの標準化が進み、jQueryを使う必要がなくなった
- React.jsなどjQueyrに代わるライブラリが出てきた
$.ajax
を使うためにjQueryをロードするのは無駄なので、jQueryを使わないなら、これを使った方がよさそう。
3. JSONとAjax
JSONとは
JSON (JavaScript Object Notation)は、軽量のデータ交換フォーマットです。人間にとって読み書きが容易で、マシンにとっても簡単にパースや生成を行なえる形式です。
http://www.json.org/json-ja.html 引用
JavaScriptの標準機能でJSONに変換できる。
a = {x:1, y:"a", z:[1,2,3]}
//オブジェクトをJSONに変換
b = JSON.stringify(a)
console.log(b)
// ⇒ "{"x":1,"y":"a","z":[1,2,3]}"
//JSONをオブジェクトに変換
c = JSON.parse(b)
console.log(c)
Ajaxで複数の情報
Ajax用のAPIは、JSONで返すのが一般的。
Ajaxの"X"
XMLのこと。
もともとXMLを返すことを想定したたが、JSONの方が便利なためJSONで返すようになった。
XMLと比較したときのJSONのメリットは
- 人が読みやすい
- 冗長でない
- プログラムにとって扱いやすい
- JavaScriptのオブジェクト記法と同じ
http://uraway.hatenablog.com/entry/2015/12/26/XML%E3%81%A8%E3%81%AF%EF%BC%9F_JSON%E3%81%A8%E3%81%AF%EF%BC%9F
https://www.gixo.jp/blog/4196/
JSONとXMLの比較(作成中)
- TODO JSON利用者が増えているグラフを表示
付録
Ajaxは流行った?
- タイトルに「Ajax」が含まれている本は、2006~2009年に発行されている。
タイトルに"ajax"が含まれる書籍 - Amazon 検索
CORS(作成中)
- JSONP