プログラミングBlog

Ajax

Ajaxとは??

Asynchronous JavaScript Xml の略

同期通信であれば、クラインアント側の操作がサーバーからのレスポンスを待たなければできなかったが、 JavaScriptHTTP通信機能(XMLHttpRequest)を用いることで非同期(asynchronous)でサーバーと通信をすることによってサーバーからのレスポンスを待たずにクライアント側が操作できるようになった。
さらに非同期(asynchronous)でサーバーからデータを取得できるため、ページ全体ではなく、ページの一部だけ更新が可能となる。 その結果、サーバー間のトラフィック量も下がる。
e-words.jp

XMLHttpRequest

サーバーとの通信をする際に使うオブジェクト
今回はこちらのオブジェクトを使ってAjaxを実装していく。

GETの場合

やりたいこと

  1. xhr.openにてAPIからデータを取得。
  2. イベントハンドラーで取得したデータをinnerTextに追記していく。
  3. リクエストを送信する。

イベントハンドラ

通信の状態が変化した際に取得できるイベントハンドラ
onreadystatechangeを利用せずに以下のイベントでも可能

イベント名 意味
loadstart リクエスト送信
progress 送受信中
timeout タイムアウト
abort リクエスト中断
load リクエスト成功
error リクエスト失敗
loadend リクエスト完了

参考サイト
developer.mozilla.org

IPO Calendar API

今回はこちらのAPIを使用しました。
株式市場の上場スケジュールを取得できるAPI
ipo-cal.appspot.com

実装の説明

  • xhr.open() 
    第一引数にメソッド名、第二引数に取得したいデータが存在するURL
  • xhr.onreadystatechange 
    通信が成功した際のステータスコード(200)が返却された場合に取得したデータをinnerTextに追記する処理を記述。
  • xhr.addEventListener
    通信の状態が変化した際のイベントを登録。
    通信の流れが知りたいのですべて書いてみる。
  • xhr.send()
    リクエストを送信
  • innerText
    なぜinnerTextなのかはこちらを参考にしました。
    改行コードを考慮するので使用。
    qiita.com

GETの結果

f:id:Tokuty:20210627220222p:plain
データを取得できているようなので無事成功。
progress... → データ取得 → Success...  → Completed... の順番で通信が行われている模様。。

POSTの場合

実装の説明

  • xhr.setRequestHeader
    どんなデータを送信するかの設定を行います。
content-Type 種類
application/x-www-form-urlencoded テキスト
application/json Json
multipart/form-data バイナリ形式

POSTの結果

Post失敗時の画像 f:id:Tokuty:20210627215917p:plain

405エラーが返却されて、できませんでした。

f:id:Tokuty:20210627213345p:plain

ResponseのAllowにPostがないので、POSTはできないようです。

f:id:Tokuty:20210627213353p:plain

405エラーとは??

blog.hubspot.jp

全体のコード

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AjaxSample</title>
</head>

<body>
    <div>
        <labe>銘柄コード取得1:</labe>
        <input id="get_code1" type="text" value="">
        <button id="xhr_get_request1">Click_Get_Code1</button>
    </div>
    <div>
        <labe>銘柄コード取得2:</labe>
        <input id="get_code2" type="text" value="">
        <button id="xhr_get_request2">Click_Get_Code2</button>
    </div>

    <button id="xhr_post_request">Click_Post</button>
    <div>
        <p id="xhr_get_response1"></p>
    </div>
    <div>
        <p id="xhr_get_response2"></p>
    </div>
    <div>
        <p id="xhr_post_response"></p>
    </div>
    <script src="./sample.js"></script>
</body>

</html>
// Ajaxとは??
// Asynchronous JavaScript XML の略

// サーバー側と非同期通信を行い、受信結果をDOM経由でページに反映する仕組み
// get
const xhr_get_request1 = document.getElementById('xhr_get_request1');
const xhr_get_response1 = document.getElementById('xhr_get_response1');

const xhr_get_request2 = document.getElementById('xhr_get_request2');
const xhr_get_response2 = document.getElementById('xhr_get_response2');

// post
const xhr_post_request = document.getElementById('xhr_post_request');
const xhr_post_response = document.getElementById('xhr_post_response');

const get_code1 = document.getElementById('get_code1');
const get_code2 = document.getElementById('get_code2');

xhr_get_request1.addEventListener('click', function () {
    // 2秒後に実行
    setTimeout(xhr_request_method, 2 * 1000, 'http://ipo-cal.appspot.com/api/ipo/', xhr_get_response1, get_code1);
}, false);

xhr_get_request2.addEventListener('click', function () {
    // 5秒後に実行
    setTimeout(xhr_request_method, 5 * 1000, 'http://ipo-cal.appspot.com/api/ipo/', xhr_get_response2, get_code2);
});

// XMLHttpRequest
const xhr = new XMLHttpRequest();

// Ajax処理 get_request
function xhr_request_method(url, xhr_response, get_code) {
    xhr.open('GET', url + get_code.value);

    xhr.send(null);

    xhr_event(xhr, xhr_response, get_code.id);

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                xhr_response.innerText += xhr.responseText + '\n';
            } else {
                xhr_response.innerText += 'failure!!\n';
            }
        }
    }
}

// Ajax処理 post_request
xhr_post_request.addEventListener('click', function () {
    xhr.open('POST', './sample.html');
    xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
    xhr.send("text");
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                xhr_post_response.innerText += xhr.responseText + '\n';
            } else {
                xhr_post_response.innerText += 'failure!!\n';
            }
        }
    }
});

// event
function xhr_event(_xhr, xhr_response, event_name) {
    // リクエスト送信をした時
    _xhr.addEventListener('loadstart', function () {
        xhr_response.innerText += `${event_name}:communication...\n`;
    });

    // データを送受信しているとき
    _xhr.addEventListener('progress', function () {
        xhr_response.innerText += `${event_name}:progress...\n`;
    });

    // タイムアウトした時
    _xhr.addEventListener('timeout', function () {
        xhr_response.innerText += `${event_name}:timeout...\n`;
    });

    // リクエストがキャンセルされた時
    _xhr.addEventListener('abort', function () {
        xhr_response.innerText += `${event_name}:abort...\n`;
    });

    // リクエストが成功した時
    _xhr.addEventListener('load', function () {
        xhr_response.innerText += `${event_name}:success...\n`;
    });

    // リクエストが失敗した時
    _xhr.addEventListener('error', function () {
        xhr_response.innerText += `${event_name}:error...\n`;
    });

    // リクエストが完了した時
    _xhr.addEventListener('loadend', function () {
        xhr_response.innerText += `${event_name}:completed...\n`;
    });
}