--- title: 【社内勉強会】Ajaxの基礎(2017/10/18) tags: 勉強会 Ajax author: yuji38kwmt slide: true --- 【社内勉強会】Ajaxの基礎(2017/10/18) # 0. はじめに ------- ## 内容 * Ajaxの基礎。`XMLHttpRequest`(ライブラリを使わずに)で理解する。 ### 前提知識 * JavaScriptの基本的な構文を理解している人 - 配列 - オブジェクト - イベント - コールバック関数 ### 注意 ここで紹介したXMLHttpRequestの使い方は、サンプル用で実務には適していません。以下の内容を考慮していません。 * エラー処理 * URLエンコード ------- ## 参考図書 ![image](https://qiita-image-store.s3.amazonaws.com/0/37903/8672c64c-9a0c-7af7-17a3-294b43dab53f.png) [『改訂新版JavaScript本格入門』技術評論社](http://gihyo.jp/book/2016/978-4-7741-8411-1) 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](https://qiita-image-store.s3.amazonaws.com/0/37903/8f6b1af6-aee6-044a-d8d9-9f3855b861cb.png) ※[Ajax - Wikipedia](https://ja.wikipedia.org/wiki/Ajax) 引用 ------- ## 従来型のWebアプリ JSPで動作を確認する。 二乗した結果を表示する画面。 ```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) {} } %>
INPUT: OUTPUT:
``` ------- ### 従来型のWebアプリの特徴 * 結果を表示する際に、ページ全体が書き換えられる - 常にぺージ全体をリフレッシュする必要がある - トラフィック量に無駄がある * サーバと通信している間、クライアント側は操作できない ------- ## Ajaxアプリ Ajax通信で結果を表示するためのServletを用意する。 ```java: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で非同期通信を実施 ```javascript: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"); } ``` ```html:ajaxform.html INPUT: OUTPUT: ``` ------- ### Ajaxアプリの特徴 * テキストボックスのみ更新される - 画面のチラツキが解消 * サーバ通信中もクライアント側で処理を継続できる - サーバ通信中に、コンソールに"after"が出力されることを確認 ------- ### XMLHttpRequestで同期通信を実施 `XMLHttpRequest.open`の3番目の引数に`false`を指定する。 ```javascript:sample.js function calculate() { //省略 //リクエストの初期化(GETで同期通信) xhr.open("GET", url, false ); //リクエストの送信 xhr.send(null); //以下のデバグ文がいつ実行されるか確認 console.log("after"); } ``` * 同期通信では、サーバ通信の完了後にコンソールに"after"が出力される。 [同期および非同期リクエスト](https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests) 参考 ------- ### XMLHttpRequestでPOSTを送信 ```java:PowServlet.java protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //doGetと同じ処理 //... } ``` ```javascript: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`メソッドを利用する ```js: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から廃止された。 ```js //昔の書き方 $.ajax({ url: "http://jsrun.it/assets/E/H/Z/t/EHZt3", success: function (data) { $("#results").append(data); }, error: function () { alert("読み込み失敗"); } }); ``` [jQuery3.0 アップグレードガイド](https://qiita.com/rana_kualu/items/65a4fb9f9b2bd3806598) 参考 ------- ## [補足] 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に変換できる。 ```javascript:ブラウザコンソール 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 スタートガイド](https://developers.google.com/maps/documentation/geocoding/start?hl=ja) [Nagoyaの緯度経度を返すAPI](https://maps.googleapis.com/maps/api/geocode/json?address=Nagoya) ------- ## 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 検索](https://www.amazon.co.jp/gp/search/ref=sr_il_ti_stripbooks?rh=n%3A465392%2Cn%3A%21465610%2Cn%3A466298%2Cp_28%3Aajax%2Cp_45%3A0%2Cp_46%3Abefore%2Cp_47%3A2020&sort=date-asc-rank&unfiltered=1&ie=UTF8&qid=1508861636&lo=stripbooks) ------- ## CORS(作成中) * JSONP ------- ## 参考サイト * [新人プログラマですがjQueryのajaxがわからなすぎて勉強したまとめ](https://qiita.com/okumurakengo/items/53020dd97382d49621ce) * [jQuery3.0 アップグレードガイド](https://qiita.com/rana_kualu/items/65a4fb9f9b2bd3806598) ------- ## JSONP