ウェブブラウザ上でAjax通信をするユースケースとして、GitHubのユーザーIDからプロフィール情報を取得するアプリケーションを作成します。作成するアプリケーションは次の要件を満たすものとします。
・GitHubのユーザーIDをテキストボックスに入力できる
・入力されたユーザーIDを元にGitHubからユーザー情報を取得する
・取得したユーザー情報をアプリケーション上で表示する
●エントリーポイント
エントリーポイントとは、アプリケーションの中で一番最初に呼び出される部分のことです。 アプリケーションを作成するにあたり、まずはエントリーポイントを用意しなければなりません。Webアプリケーションにおいては、常にHTMLドキュメントがエントリーポイントとなります。 ウェブブラウザによりHTMLドキュメントが読み込まれたあとに、HTMLドキュメント中で読み込まれたJavaScriptが実行されます。
●プロジェクトディレクトリを作成
このプロジェクトで作成するファイルは、必ず文字コード(エンコーディング)をUTF-8、改行コードをLFにしてファイルを保存します。
●ファイルの用意
index.jsにはスクリプトが正しく読み込まれたことを確認できるよう、コンソールにログを出力する処理だけを書いておきます。
●ウェブブラウザとDOM
DOM(Document Object Model) とは、HTMLドキュメントのコンテンツと構造をJavaScriptから操作できるオブジェクトです。 DOMではHTMLドキュメントのタグの入れ子関係を木構造で表現するため、DOMが表現するHTMLタグの木構造を DOMツリー と呼びます。
を表現する document グローバルオブジェクトがあります。 document グローバルオブジェクトには、指定したHTML要素を取得したり、新しくHTML要素を作成するメソッドが実装されています。
→なるほど
document グローバルオブジェクトを使うことで、先ほどのindex.html に書かれたHTMLをJavaScriptから操作できます。
→そうなんだ
今回のユースケースでもGitHubのAPIから取得したデータを元に、動的にDOMツリーを操作して画面の表示を更新します。
→DOMツリーの操作は、documentオブジェクトを通して行う?
→そう。documentオブジェクトは、HTML要素を操作できる(取得や作成など)
DOMは言語機能(ECMAScript)ではなくブラウザが実装しているAPIです。 そのため、DOMを持たないNode.jsなどの実行環境では使えず、documentのようなグローバルオブジェクトも存在しないことには注意が必要です。
→どういうこと?
→DOMは「ブラウザオブジェクト」ということになるか。
→documentオブジェクトは、ブラウザオブジェクトだった気がする。
GitHubのAPIを呼び出す処理を実装していきます。
GitHubのAPIを呼び出すためにはHTTP通信をする必要があります。
ウェブブラウザ上でJavaScriptからHTTP通信するために、Fetch APIという機能を使います。
●Fetch API
Fetch APIはHTTP通信を行ってリソースを取得するためのAPIです。
Fetch APIを使うことで、ページ全体を再読み込みすることなく指定したURLからデータを取得できます。
Fetch APIは同じくHTTP通信を扱うXMLHttpRequestと似たAPIですが、より強力で柔軟な操作が可能です。
リクエストを送信するためには、fetchメソッドを利用します。
fetchメソッドにURLを与えることで、HTTPリクエストが作成され、サーバーとのHTTP通信を開始します。
GitHubにはユーザー情報を取得するAPIとして、https://api.github.com/users/GitHubユーザーIDというURLが用意されています。
GitHubのユーザーIDには、英数字と-(ハイフン)以外は利用できないため、ユーザーIDはencodeURIComponent関数を使ってエスケープしたものを結合します。
encodeURIComponentは/や%などURLとして特殊な意味を持つ文字列をただの文字列として扱えるようにエスケープする関数です。
●レスポンスの受け取り
GitHubのAPIに対してHTTPリクエストを送信しましたが、まだレスポンスを受け取る処理を書いていません。 次はサーバーから返却されたレスポンスのログをコンソールに出力する処理を実装します。
fetchメソッドはPromiseを返します。このPromiseインスタンスはリクエストのレスポンスを表すResponseオブジェクトでresolveされます。 送信したリクエストにレスポンスが返却されると、thenコールバックが呼び出されます。
次のように、Responseオブジェクトのstatusプロパティからは、HTTPレスポンスのステータスコードが取得できます。 また、ResponseオブジェクトのjsonメソッドもPromiseを返します。これは、HTTPレスポンスボディをJSONとしてパースしたオブジェクトでresolveされます。 ここでは、書籍用に用意したjs-primer-exampleというGitHubアカウントのユーザー情報を取得しています。
Responseオブジェクトのstatusプロパティからは、HTTPレスポンスのステータスコードが取得できます。
また、ResponseオブジェクトのjsonメソッドもPromiseを返します。
1 2 3 4 5 6 7 8 9 |
const userId = "js-primer-example"; fetch(`https://api.github.com/users/${encodeURIComponent(userId)}`) .then(response => { console.log(response.status); // => 200 return response.json().then(userInfo => { // JSONパースされたオブジェクトが渡される console.log(userInfo); // => {...} }); }); |
●エラーハンドリング
HTTP通信にはエラーがつきものです。
そのためFetch APIを使った通信においても、エラーをハンドリングする必要があります。
たとえば、サーバーとの通信に際してネットワークエラーが発生した場合は、ネットワークエラーを表すNetworkErrorオブジェクトでrejectされたPromiseが返されます。
すなわち、thenメソッドの第二引数かcatchメソッドのコールバック関数が呼び出されます。
リクエストが成功したかどうかはResponseオブジェクトのokプロパティで認識できます。
okプロパティは、HTTPステータスコードが200番台であればtrueを返し、それ以外の400や500番台などならfalseを返します。
この記事へのコメントはありません。