【jQuery】getJSON()と【javascript】XMLHttpRequestの違い
先日JSONの取得でこの二つを使った取得方法について紹介しました。
前述では製作しながらのため解説が文法よりではなかったです。
両方しっかりと調べてみたのでこの記事では違いについてみていきたいと思います。
本記事の内容
今回使用するJSONは以前にも使用した単純なこのJSONを使います。
{"name" : "ディープインパクト" ,"speed" : 100 ,"stamina" : 90}
getJSONについて
- getJSON関数についておさらい
- 取得状態について
- 取得状態ごとの処理
getJSON関数についておさらい
getJSONの使い方です。
$.getJSON( url , function(data){//処理});
このようにJSONファイルのURLを引数に取り、返り値のdataを用いて取得後の実行関数を記述します。
取得状態について
上記の場合だと取得完了時にしか動かないですよね。取得失敗した場合などどうなるのでしょうか。
そう思いながら調べていると「$.getJSON()」は「$.ajax()」の略式記法だということがわかりました。
「$.getJSON()」を「$.ajax()」で表現すると以下のようになります。
$.ajax({dataType: "json",url: url,data: data,success: success});
また、$.ajax()と同様に$.getJSON()もXHR(XMLHttpRequest)のスーパーセットであるjqXHR(jQuery XMLHttpRequest)が返されます。
$.ajax()でJSON形式を指定する場合も$.getJSON()で取得する場合もJSON形式にパースされています。
jqXHRはXHRと完全に同様ではないもののいくつかプロパティやメソッドを使用することができ、独自のメソッドもあります。
XHRでは「.readyState」や「.status」によってクライアントの状態やHTTPステータスコードを取得することで、通信状態を把握したりします。
また、「.readyState」や「.status」のイベントハンドラーである「.onreadystatechange」を使用することで状態の切り替わったことがわかります。
しかし、jqXHRには「.onreadystatechange」はサポートされていません。
その代わりに「.done」「.fail」「.always」「.statusCode」を使うことで状態を把握します。
これで、最初の「取得に失敗したら」というところが解決できますね。
「.done」は成功した場合、「.fail」は失敗した場合、「.always」は完了した際「.done」「.fail」よりも後に呼び出されます。
取得状態ごとでの処理
取得状態についての取得方法が分かったので実際に使用してみようと思います。
デモページはこちらです。
実行後はこのようになります。
2番目は引数ではなく「.done」で処理を行ったものです。
3番目はないファイルを指定し、「.fail」のイベントを発火させています。
4番目は「.always」を利用してみた形です。
function getJsonCmp() {let url = "json/hourse.json";let getStartTime = Date.now();let response = $.getJSON(url).done(function(data) {$("#resJsonCmp").html("<p>NAME:" + data.name + " <br>SPEED:" + data.speed +"<br>STAMINA:" + data.stamina + "</p>");}).fail( function(){$("#resJsonCmp").html("<p>取得失敗しました。</p>");});let getFinishTime = Date.now();response.always(function() {let prcTime = getFinishTime-getStartTime;$("#resJsonCmp").append("<p>処理時間は" + prcTime + "ミリ秒でした。</p>")});}
getJSON返り値であるオブジェクトを変数に格納しています。
今回は処理時間を計測してみました。
alwaysのdoneまたはfail後に発火する特性から処理終了したタイミングで「always」によって計測時間を表示しています。
XMLHttpRequestについて
- XMLHttpRequestの使い方
- 取得状態
- 取得状態ごとの処理
XMLHttpRequestの使い方
使い方は以下のような流れになります。
オブジェクト生成しておきます。自明ですがXMLHttpRequest()がコンストラクタです。
let request = new XMLHttpRequest();
次にリクエストを開始するためopen()メソッドを使います。
HTTPメソッドの指定と、取得するファイルのURLを指定します。
request.open("GET" , url);
レスポンスタイプを指定します。今回はJSONで取得するためJSON指定します。
request.responseType = "json";
リクエストを送信します。
request.send();
送信が完了し取得できると以下のメソッドで取得することができます。
request.response;
これだけだと取得が成功したのか失敗したのかわかりません。
そのため次で取得状態を見ていきます。
取得状態
エラーや完了したなどの状態の取得を見ていきます。
状態の確認には二種類あります。クライアントの状態を知るものと、HTTPのステータスコードを知ることができるものです。
まずはクライアントの状態を知るものです。
- 0:open()はまだ呼ばれていない状態
- 1:open()は呼び出し済み
- 2:send()が呼び出し済み
- 3:ダウンロード中
- 4:操作完了
というように5種類あります。下記のように取得します。
request.readyState
次にHTTPのステータスコードです。下記のように取得します。404はエラーのようなものです。
request.status
また、「readyState」は状態が変わった場合「onreadystatechange」というイベントハンドラーで知ることが可能です。
これを使うことで状態ごとの処理を切り分けることが可能です。
取得状態ごとの処理
今回は完了した場合での操作にフォーカスします。
デモページはこちらです。
「readyState」及び「status」の両方を満たした場合が成功している状態です。なのでその時に処理を発生させます。
以下のコードを見てください。
request.onreadystatechange = function() {//readyState 4:操作完了 status 200:HTTPリクエスト成功if (request.readyState === XMLHttpRequest.DONE) {if(request.status === 200){//処理}}};
request.readyStateがXMLHttpRequest.DONEと一致した際に処理側に入るようにしています。
XMLHttpRequest.DONEは「4」で固定値です。そのほかの値など知りたい際はこちらから。
ready.stateは200の時にしています。Httpレスポンスステータスコードについてはこちらにあります。
デモページでコンソール確認してもらえれば「.readyStatus」の値が順に出力されているのがわかります。
これらはXMLHttpRequestのプロパティをもとに切り分けています。
XMLHttpRequestではイベントでの切り分けもできます。
イベントの場合は以下のようになります。
function procEvent(event) {console.log(event.type);}function listenerJSON(request) {request.addEventListener("loadstart" , procEvent );request.addEventListener("load" , function(){console.log("load");let result = request.response;let elem = document.createElement("p");let parElem = document.getElementById("resXhrJson");parElem.innerHTML="";parElem.appendChild(elem);elem.innerHTML = "NAME:" + result.name + " <br>SPEED:" + result.speed +"<br>STAMINA:" + result.stamina ;} );request.addEventListener("loadend" , procEvent );request.addEventListener("progress" , procEvent );request.addEventListener("error" , procEvent );request.addEventListener("abort" , procEvent );}function xhrJson() {const url = "json/hourse.json";//XMLHttpRequestオブジェクト生成const request = new XMLHttpRequest();//リスナー起動listenerJSON(request);//リクエストの初期化request.open("GET" , url);//リクエストプロパティのレスポンス型の定義request.responseType = "json";//リクエストの送信request.send();request.onerror= function(){console.log("asda");};}
リスナーにそれぞれを登録しておき、イベントが発火した際に関数が実行されます。
それぞれは以下のタイミングで呼び出されます。
- loadstart:リクエストがデータを読み込み始めたとき(onloadstart)
- load:トランザクション成功時(load)
- loadend:「load」、「abort error」の後にリクエストが成功と失敗のどちらでも呼びされます。
- progress:データ受信時に発生
- abort:リクエストが中断されたときに発生
- error:リクエストでエラーが発生した時
上記のような書き方とよく使われる「.onload」などの書き方も可能です。こちらの方が体感的にわかりやすい方もいるかもしれませんね。
デモページで実行するとコンソールに処理タイプを表示してますのでどのような流れか追ってみてください。
相違点など
.getJSONとxmlHttpRequestですが途中で気づいたと思います。
ほとんど一緒です。
JQueryかネイティブかの違いぐらいです。
状態の取得などやや異なる点もありますが、どちらでもできることには大差ないのではないでしょうか。
getJSONは取得時にJSONに強制的にパースされてしまいます。(テキストで受け取って$.parseJSONを使う方法はあります。)
対してxmlHttpRequestではテキストで受け取ってJSONにパースするなどの方法をとることもできます。
反対にJSONデータをテキストに変えることも可能です。
結論
好きな方使いやすいほうを使ってください。どちらでも同じようなことができます。
デモページ(getJSON)
デモページ(xmlHttpRequest)
まとめ
両方がどのような性質のものかわかってもらえたのではないかと思います。
初心者の方が扱うならjQueryでgetJSONを使いましょう。ネイティブの方を使用するのは学習コストが高いかもしれません。
時間をかけれるならネイティブの方で理解しておくとどのような動きをしているかわかります。