非同期通信とURLパラメーター

・非同期通信

リクエスト後に、ブラウザが再読み込みされることなく、ブラウザ画面の情報の一部分のみが更新される通信方法のこと。
ユーザーからすると待ち時間のストレスがなくWebアプリケーションの操作ができる。

この非同期通信をJavaScriptで実装する際、これらの機能はAjaxと呼ぶ。

・Ajax(エイジャックス)

JavaScriptを使用して、非同期通信を行う処理のプログラム手法のこと。
"Asynchronous JavaScript + XML"の略。

______________________

・非同期通信時のレスポンス内容

非同期通信では、HTMLではなくデータを返却する。
それをJavaScriptで受け取り、すでに表示されているHTMLを部分的にレンダリングする仕組み。

図17.001

・エンドポイント

Ajaxでやり取りする際の、データ返却のアクションを実行するためのURL。

まず、Ajaxを実現するためには、Ruby on Railsのコントローラーでのレスポンスを、HTMLではなくjsonなどのデータ形式で返却する必要がある。
そのデータを取得する時にアクセスするためのURL。

エンドポイントには「〇〇のid」というパラメーターを渡す。

______________________

コントローラーのアクションで返却するレスポンスはデータである・・・
>>データが返却されるためのURL(ルーティング)の設定

・URLパラメーター

サーバーに情報を送るために記載するURL末尾の文字列。
URLパラメーターで送信した情報は、params[:id]などで取得・使用する。非同期通信では、このURLパラメーターを活用し、サーバーへデータを送る。

URLパラメーターには数種類ある。

・queryパラメーター

「?」以降に情報を綴るURLパラメーター。

http://sample.jp/?name=tanaka     #   ?<変数名>=<値>。

例のURLでparams[:name]とすると、tanakaが戻り値となる。

・pathパラメーター

http://tweets.jp/tweets/1

pathパラメーターで指定するのは「リソースを識別する場合」。

______________________

>>レスポンス(返却されるデータ)の設定

・データ形式

コンピューター上でデータをやり取りする際の形式のこと。
CSV, XML, JSONなどがあり、CSVは「スプレッドシート」や「エクセル」で出力できる。
・・・プログラミングではJSONが多く使用されている。

JSON:JavaScriptObjectNotationの略。
JavaScriptにおけるオブジェクトの表記でり、データをJavaScriptのオブジェクト指向で取り扱う場合、非常に相性が良い。


______________________

・エンドポイントにアクセスするには
「アクセス = イベントが発火した」際に、「何らかの処理が」実行される

・イベントハンドラー

イベントが発火した時に実行される処理のこと。
具体的には「クリックした時に〇〇をする」といったような処理。

>>

「何らかの処理」の部分:
ルーティングより生成された、エンドポイントへのリクエスト処理を記述する。

エンドポイントへリクエストを送ると、JSON形式のデータが返却される。そのデータを使用して部分的に再描画するよう変更する。

・・・この「エンドポイントへリクエストし、JSON形式のレスポンスを受け取る」という一連の流れが、Ajaxによって実現できる。
JavaScriptから、Ajaxによるリクエストを送るためのオブジェクトがXMLHttpRequest。

・XMLHttpRequest

Ajaxを可能にするためのオブジェクトで、サーバーにHTTPリクエストを非同期で行うことができる。
XMLHttpRequestにある、様々なメソッドを使用してサーバーへリクエストを送る。

ビューファイルにidを埋め込んで、JavaScriptで取得できるように、カスタムデータ属性を用いる。

・カスタムデータ

HTMLに対して任意の属性を持たせられる機能のこと。
data-<情報>として、属性値には文字列で情報を与える。

<div class="sample" data-id = "1">
</div>

JavaScriptを併用する際には、表示されているデータのidなどの情報を付与すると便利。

>>>

エンドポイントを呼び出すために、XMLHttpRequestを使用してHTTPリクエストを行う。
オブジェクトを生成する。これで変数XHRから、XMLHttpRequestのメソッドを使用できるようになる。

const XHR = new XMLHttpRequest();

・open

XMLHttpRequestで定義されているメソッドで、どのようなリクエストをするのかを指定するメソッド(リクエストを初期化できる)。

XHR.open("GET", `/posts/${postId}`, true);
第一引数にはHTTPメソッド、第二引数にはパス、第三引数には非同期通信であるかをbooleanで記述。

          記述場所                   目的                         以降で使用する際の記述
          第一引数       HTTPメソッドの指定                     GET
          第二引数              パスの指定                      /posts/${postId}
          第三引数       非同期通信のON/OFF                     true

・responseType

XMLHttpRequestで定義されているメソッドで、レスポンスの形式を指定するメソッド。リクエストを送る際にあらかじめ、レスポンスとして欲しい情報の形式を指定する必要がある。
JSON形式のデータをレスポンスさせたい場合、下記記述。

XHR.responseType = "json";

>>

設定した情報をサーバーサイドへ送信する時には、sendメソッド。

・send

XMLHttpRequestで定義されているメソッドで、リクエストを送信できる。

>>

コントローラで処理されて、レスポンスを受け取るためにはonloadプロパティ。

・onload

レスポンスなどの受信が成功した場合に呼び出される、イベントハンドラーのこと。XMLHttpRequestで定義されているプロパティ。

XHR.response:レスポンスされてきたJSONにアクセスできる。(下記参照)

# コントローラ上の記述

def checked
  post = Post.find(params[:id])
  if post.checked
    post.update(checked: false)
  else
    post.update(checked: true)
  end
  item = Post.find(params[:id])     # XHR.response.postで取得できる。
  render json:{ post: item }
end

______________________

・レスポンスがエラーの場合

レスポンスのステータスコードが200以外(レスポンスが存在しないなど何かしらの不具合があった場合に返却されるコード)の場合。
また、ステータスコードには下記のような種類があります。

ステータスコード                     内容
           100~                        処理の継続中
           200~                        処理の成功
           300~                       リダイレクト
           400~                       クライアントのエラー
           500~                       サーバーのエラー

→ statusというメソッドを用いることで確認できる。

XHR.onload = () => {
   if (XHR.status != 200) {
      alert(`Error ${XHR.status}: ${XHR.statusText}`);        # XHR.statusTextによって、エラーが生じたオブジェクトに含まれるエラーメッセージが表示される。
      return null;                                            # return null; によって、JavaScriptの処理から抜け出す。(エラーが出た場合に、以降に記述されている処理を行わないため)
   }

   const item = XHR.response.post;
   if (item.checked === true) {
      post.setAttribute("data-check", "true");
   } else if (item.checked === false) {
      post.removeAttribute("data-check");
   }
};

______________________

非同期通信では、ページの読み込みが発生しないため、リロードなどでページを更新しない限り、コントローラ記述の関数は実行されない。

「ページを読み込んだら関数を実行する」のではなく、「一定の時間ごとに、自動で関数を実行する」仕様に変更する。

・setInterval

一定の間隔(時間)ごとに指定した関数などを実行できるメソッド。
第一引数に実行する関数を指定し、第二引数に時間(ミリ秒)を指定する。

setInterval(check, 1000);    # check関数が1秒に1度実行される

trueを付与する処理とfalseを付与する処理が、連続でおこなわれている時は処理を止める分岐を追加記述する。

function check() {
 const posts = document.querySelectorAll(".post");
 posts.forEach(function (post) {
   if (post.getAttribute("data-load") != null) {
     return null;
   }

   #  中略


 });
}
setInterval(check, 1000);

・FormData

フォームに入力された値を取得できるオブジェクト。

new FormData(フォームの要素);

引数にフォームの要素を渡すことで、オブジェクトを生成し、そのフォームに入力された値を取得できる。

・insertAdjacentHTML

指定したHTMLなどを、特定の要素に描画できるメソッド。

要素.insertAdjacentHTML("afterend", HTML);

第一引数には、要素のどこに描画するのかを指定。
第二引数には描画するHTML自体を渡す。あらかじめHTMLなどの変数に描画したいHTMLを代入しておき、変数を渡してあげると保守性も上がる。

値(第一引数)                       内容
beforebegin                 要素の直前に挿入
   afterend                    要素の直後に挿入
 afterbegin                   内部の最初の子要素の前に挿入
 beforeend                   内部の最後の子要素の後に挿入

・insertAdjacentHTML
指定した要素にHTMLを追加する。
下記の例では、第一引数にafterendを指定することで、要素listの直後に挿入できる。

list.insertAdjacentHTML("afterend", HTML);

______________________

コントローラーのアクションと、JavaScriptの処理が重複していると、画面をリロードする度に同じ処理がされることがある。

・preventDefault()

標準設定されている(Default)イベントを阻止する(prevent)メソッド。

標準設定されているイベントの例                        挙動
submitボタンでclickする                        ・指定先のURLへ画面遷移
                                                                  ・データ送信
チェックボックスでclickする                ・チェックが入る(外れる)
e.preventDefault();

2020/11/21



2020/11/15


この記事が気に入ったらサポートをしてみませんか?