Ajax通信でhatenablogのブックマークを取得しよう！！(生のjavascripで実装)


#はじめに
この記事ではjQueryなどのライブラリを使わずにajxa通信をjavscriptで実装する方法を示していきます。
hatenablogのブックマーク一覧をajax通信で取得していきます。

ajax通信について初見の方は以下が参考になります。
https://qiita.com/katsunory/items/9bf9ee49ee5c08bf2b3d

##目次

1. サーバーサイドから「はてなブックマークエントリー情報取得API」(以下、はてブAPIとする)にアクセスする。

2. クライアントページを作成。


##1.サーバーサイドから「はてなブックマークエントリー情報取得API」にアクセスする。
まずは、phpスクリプトではてぶAPIにアクセスする為のコードを用意します。


```php:bm.php
<?php
    //出力文字コード, 内部文字コードを宣言。
    mb_internal_encoding('utf-8');
    mb_http_output('utf-8');
    //レスポンスヘッダーのコンテンツタイプを宣言
    header('Content-type: application/json;charset=UTF-8');
    //はてぶAPIへの問い合わせURLを組み立て。
    $url = 'http://b.hatena.ne.jp/entry/jsonlite/?url='.$_GET['url'];
    //ファイルの内容を全て文字列に読み込み、結果をそのまま出力
    print(file_get_contents($url, false, stream_context_create(['http' => ['header' => 'User-Agent:  Mysample']])));
```
 
ここでは入力されたURLを元に問い合わせURLを作成し、その結果をJSONデータとして出力する。
という流れだけ理解しておいてください。
bm.phpをサーバに配置した上で以下のようなURLでブラウザーから実行してみましょう。クエリ情報の「url=」以下には、ブックマーク情報を取得したいページのURLを指定します。


```php:url
http://localhost/.../bm.php?url=http://www.wings.msn.to/
```
はてブAPIから取得した結果がJSON形式で得られていればまずは成功です。

##2.クライアントページを作成する。

```bm.html
<from>
    <label for='url'>URL: </label>
        <input id='url' type='text' name='url' size='50' value='http://www.wings.msn.to/'/>
        <input id="btn" type='button'  value="検索">
</from>
<div id="result"></div>
<script type='text/javascript' src='./bms.js'></script>
```

```js:bm.js
document.addEventListener('DOMContentLoaded', function(){
//検索ボタンをクリックした時に実行されるコード
 document.getElementById('btn').addEventListener('click', function() {
    let result = document.getElementById('result');
   //XMLHttpRequesオブジェクトを定義
   let  xhr = new XMLHttpRequest();
//非同期通信時の処理を定義
   xhr.onreadystatechange = function() { 

    if(xhr.readyState === 4) { //通信が完了した時。
        if(xhr.status === 200){//通信が成功した時。
            //取得したテキストデータをJSONオブジェクトとして生成。
            let data = JSON.parse(xhr.responseText);
            if(data === null) {

                result.textContent = 'ブックマークは存在しませんでした。'
            
            }else{
            //ブックマークが取得できた場合、ユーザリストを表示。
            let bms = data.bookmarks;
            let ul = document.createElement('ul');
            for(let i = 0; i < bms.length; i++) {
　　　　　　　　　 //<li>, <a>, テキスト要素を生成
                let li = document.createElement('li');
                let anchor = document.createElement('a');
                anchor.href = 'http:b.hatena.ne.jp/' + bms[i].user;
                let text = document.createTextNode(bms[i].user + bms[i].comment);
                //テキスト→<a>→<li>→<ul>の順にノードを組み立て
                anchor.appendChild(text);
                li.appendChild(anchor);
                ul.appendChild(li);
            }
            //クラス名が'result'のHTML要素の小要素に<ul>を代入(置換)。
            result.replaceChild(ul, result.firstChild);
        }

        
        }else{
            //通信に失敗した時
            result.textContent = 'サーバーエラーが発生しました。';
        }

    }else{
        //通信が完了する前
        result.textContent = '通信中.....';
    }
   }
   //サーバとの非同期通信を開始
   xhr.open('GET', 'bms.php?url=' + encodeURIComponent(document.getElementById('url').value), true);
   xhr.send(null);

}, false);

}, false);
```

複雑なコードに思うかもに知れませんか、ポイントとなるのは条件分岐の条件がxhr.readyState = 4となっている処理部分だけです。
サーバーから返されたJSONデータは、responseTextプロパティで取得できます。ただし、そのままでは単なるテキストなので、JSON.parseメソッドでjavascriptオブジェクト(配列)に変換しておきましょう。
あとは変換後のオブジェクトbmsを分解してhtml要素を組み立てていきます。


<hr>



参考までにreadyState/statusプロパティで、通信状態や応答ステータスを確認します。
readyState/statusプロパティの戻り値は以下の通りです。

#readyStateプロパティの戻り値
| 戻り値      |       概要 |
|:-----------------|------------------:|
| 0      |未初期(openメソッドが呼び出されていない)|      
| 1 　　　|ロード中(openメソッドが呼び出されたが,sendメソッドが呼び出されていない|
| 2      |ロード済み(sendメソッドは送信されたが,応答ステータス/ヘッダーは未取得)|
| 3      | 一部応答を取得(応答ステータス/ヘッダーにみ取得,本体は未取得)|      
| 4      | 全ての応答データを取得済み。|

###statusプロパティの戻り値
| 戻り値      |       概要 |
|:-----------------|------------------:|
|200|OK(処理成功)|      
|401|Unauthorized(認証が必要)|
|403| Forbidden(アクセスが拒否された)|
|404| Not Found(リクエストされたリソースが存在しない)|      
|500| Internal Server　Error (内部サーバーエラー　)|
|503| Service Unavailable(要求したサーバーが利用不可)|


##結果
以下のようにブラウザで表示れれば、成功です。


<img width="1440" alt="スクリーンショット 2020-05-04 12.14.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317296/9a0e1dba-5461-207f-5fc6-f287c92c640f.png">

##参考にした図書

javascrpt本格入門
https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88JavaScript%E6%9C%AC%E6%A0%BC%E5%85%A5%E9%96%80-%EF%BD%9E%E3%83%A2%E3%83%80%E3%83%B3%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AB%E3%82%88%E3%82%8B%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E7%8F%BE%E5%A0%B4%E3%81%A7%E3%81%AE%E5%BF%9C%E7%94%A8%E3%81%BE%E3%81%A7-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B-ebook/dp/B01LYO6C1N