【備忘録】Ajax について勉強したのでまとめてみる: XMLHttpRequest


## はじめに

AJAX とは何？

AJAX とはプログラミング言語ではなく、 Asynchronous JavaScript AND XMl の略。
AJAX はシンプルに以下のコンビネーションを使う。

- ブラウザ上ビルトインの XMLHttpRequest オブジェクト(サーバーにデータをリクエストするため)
- JavaScript と HTML DOM(データの表示または使用のため。)

## 役割:

- データの送受信を非同期に行う
- 全体のページをリロードせずに、必要なアップデートを早く入れ込むことができるのでよりユーザーのアクションに対し早く、レスポンスできる！
- ほとんどは XML でなく JSON を使う

![](https://user-images.githubusercontent.com/69213242/138975513-8981f357-60c3-4abd-bca4-f10195468360.png)

## XmlHttpRequest(XHR) オブジェクトとは？

- ブラウザの JS 環境により提供されるオブジェクトの形をした API
- クライアントとサーバー間のデータ転送手段
- HTTP 以外の他のプロトコルとも使える
- XML 以外の JSON やテキストのデータと使える

### Ajax call の呼び方はたくさんある

(ライブラリや他のメソッドを使ったり...)

- Axios
- Fetch API(ブラウザ内に組み込まれた api!)
- jQuery
  などなど...

## XmlHttpRequest を使う流れ

1. ウェブページ内でイベント発生(ページがロードされたり、ボタンがクリックされたり)
2. JavaScript により XMLHttpRequest オブジェクト を作る
3. XMLHttpRequest オブジェクトがウェブサーバーにリクエストを送信する
4. サーバーがリクエストを処理する
5. サーバが Web ページにレスポンスを送信する
6. JavaScript によりレスポンスを読む
7. JavaScript によりアクションが実行(ページのアップデートとか)

### XMLHttpRequest オブジェクトを使いローカルに保存したテキストを読み込む

```html
<!-- ボタンクリックでリクエストを送信する　-->
<button id="button">Get Text File</button>
<br />
<div id="text"></div>
```

```js
document.getElementById("button").addEventListener("click", loadText);

function loadText(){
    // XHR オブジェクトを作る
    const xhr = new XMLHttpRequest();
    // OPEN -type, url/file, async
    xhr.open("GET", "sample.txt", true);

// Optional - Used for loaders
    xhr.onprogress = function(){
        console.log("ONPROGRESS-READYSTATE: ", xhr.readyState)
    }

// onloadはresponseがreadyの時初めて実行される
    xhr.onload = function() {
        if(this.status === 200) {
            console.log("READYSTATE:", xhr.readyState)；   // 4
            document.getElementById("text").innerHTML = this.responseText;
        } else if((this.status = 400)){
            document.getElementById("text").innerHTML = "Not Found";
        }
    }

    xhr.onerror = function() {
        console.log("Request Error...")
    }

       // xhr.onreadystatechange = function () {
        //   console.log("READYSTATE: ", xhr.readyState);    // 2.3.4
        //   if (this.readyState == 4 && this.status == 200) {
        //     console.log(this.responseText);
        //   }
        // };

    // Sends request
    xhr.send();
}

```

XHR の readyState request の一覧

       XHR readyState request
       0: request not initialized
       1: server connection established
       2: request received
       3: processing request
       4: request finished and response is ready

       HTTP statuses
       200: "OK"
       403: "Forbidden"
    　 404: "Not Found"

### XMLHttpRequest オブジェクトを使いローカルに保存した JSON ファイルを読み込む

```html
<button id="button1">Get User</button>
<button id="button2">Get Users</button>
<br />
<h1>User</h1>
<div id="user"></div>
<h1>Users</h1>
<div id="users"></div>
```

```js
document.getElementById("button1").addEventListener("click", loadUser);
document.getElementById("button2").addEventListener("click", loadUsers);

function loadUser() {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "user.json", true);

  xhr.onload = function () {
    if (this.status == 200) {
      console.log(this.responseText); // Json item
      // var user = this.responseText // parseしないとuser.nameするとundefined
      var user = JSON.parse(this.responseText);

      var output = "";
      output +=
        "<ul>" +
        "<li>ID: " +
        user.id +
        "</li>" +
        "<li>Name: " +
        user.name +
        "</li>" +
        "<li>Email: " +
        user.email +
        "</li>" +
        "</ul>";
      document.getElementById("user").innerHTML = output;
    }
  };

  xhr.send();
}

function loadUsers() {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "users.json", true);

  xhr.onload = function () {
    if (this.status == 200) {
      console.log(this.responseText); // Json item
      // var user = this.responseText // parseしないとuser.nameするとundefined
      var users = JSON.parse(this.responseText);

      var output = "";

      for (var i in users) {
        output +=
          "<ul>" +
          "<li>ID: " +
          users[i].id +
          "</li>" +
          "<li>Name: " +
          users[i].name +
          "</li>" +
          "<li>Email: " +
          users[i].email +
          "</li>" +
          "</ul>";
      }
      document.getElementById("users").innerHTML = output;
    }
  };

  xhr.send();
}
```

### XMLHttpRequest オブジェクトを使い外部 api から情報を読み込む

```html
<button id="button">Load GitHub Users</button> <br /><br />
<h1>GitHub Users</h1>
<div id="users"></div>
```

```js
document.getElementById("button").addEventListener("click", loadUsers);
// Load GitHub Users
function loadUsers() {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "https://api.github.com/users", true);

  xhr.onload = function () {
    if (this.status == 200) {
      var users = JSON.parse(this.responseText);
      var output = "";

      for (var i in users) {
        output +=
          '<div class="user">' +
          '<img src="' +
          users[i].avatar_url +
          '" width="70" height="70">' +
          "<ul>" +
          "<li>ID:" +
          users[i].id +
          "</li>" +
          "<li>Login:" +
          users[i].login +
          "</li>" +
          "</ul>" +
          "</div>";
      }

      document.getElementById("users").innerHTML = output;
    }
  };
  xhr.send();
}
```

### 参考

[AJAX Crash Course (Vanilla JavaScript) by Traversy Media](https://youtu.be/82hnvUYY6QA)

[W3](https://www.w3schools.com/js/js_ajax_intro.asp)

[MDN](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest)