勉強会
Ajax

【社内勉強会】Ajaxの基礎(2017/10/18)

【社内勉強会】Ajaxの基礎(2017/10/18)

0. はじめに


内容

  • Ajaxの基礎。XMLHttpRequest(ライブラリを使わずに)で理解する。

前提知識

  • JavaScriptの基本的な構文を理解している人
    • 配列
    • オブジェクト
    • イベント
    • コールバック関数

注意

ここで紹介したXMLHttpRequestの使い方は、サンプル用で実務には適していません。以下の内容を考慮していません。

  • エラー処理
  • URLエンコード

参考図書

image
『改訂新版JavaScript本格入門』技術評論社
2016年発売で、ES2015に対応。


目次

  1. XMLHttpRequestでAjax
  2. ライブラリでAjax
  3. JSONとAjax

1. XMLHttpRequestでAjax


Ajaxとは

Asynchronous JavaScript + XMLの略。

JavaScript(XMLHttpRequestオブジェクト)を利用してサーバ側と非同期通信を行い、受け取った結果をDOM経由でページに反映するしくみ

※ 『JavaScript本格入門』P389 引用


従来型のWebアプリとAjaxアプリの比較した画像

image.png

Ajax - Wikipedia 引用


従来型のWebアプリ

JSPで動作を確認する。
二乗した結果を表示する画面。

form.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を用意する。

PowServlet.java
/**
 * クエリパラメタ"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で非同期通信を実施

sample.js
/**
 * 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");
}
ajaxform.html
<!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を指定する。

sample.js
function calculate() {
  //省略

    //リクエストの初期化(GETで同期通信)
    xhr.open("GET", url, false );
    //リクエストの送信
    xhr.send(null);
    //以下のデバグ文がいつ実行されるか確認
    console.log("after");
}
  • 同期通信では、サーバ通信の完了後にコンソールに"after"が出力される。

同期および非同期リクエスト 参考


XMLHttpRequestでPOSTを送信

PowServlet.java
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      //doGetと同じ処理
      //...
    }
sample.js
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メソッドを利用する

sample.js
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("読み込み失敗");
    }
});

jQuery3.0 アップグレードガイド 参考


[補足] 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に代わるライブラリが出てきた

http://www.buildinsider.net/hub/survey/201606-popularjs

$.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で返すのが一般的。

Google Map API スタートガイド

Nagoyaの緯度経度を返すAPI


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

参考サイト


JSONP