Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

by yuji38kwmt
1 / 30

【社内勉強会】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

yuji38kwmt
愛知のIT企業で修行しております。2018年4月に転職しました。 基本的に自分用のメモとして、記事を書いております。 所属先の見解とは一切関係ありません。 https://qiita.com/yuji38kwmt/items/a474ad97e0d86f6081a2
kurusugawa
「いいソフトウェアを楽に作る」技術を追求する企業。今は、機械学習、画像認識中心。
http://kurusugawa.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした