プログラミング

ページ全体を再読み込みすることなくAjaxでデータを取得する方法

hebishima.shogo

はい、hebiです。

ページ全体を再読み込みすることなく一部のデータを取得したいことがあると思います。
その場合は、Ajaxを利用することで必要なデータのみを取得することができます!

今回はAjaxを利用したデータの取得方法を記事にしたいと思います。

スポンサーリンク

Ajaxとは

Ajax(Asynchronous JavaScript and XML)は、ウェブ開発における技術の1つです。
Ajaxを利用しない場合は、ページ全体を再読み込みする必要があったため、ユーザーエクスペリエンスが低下する場合がありました。しかし、Ajaxを使用すると、ページ全体を再読み込みすることなく、サーバーから欲しいデータのみを取得し、ページの一部だけを更新することができます。

今回はJavaScriptライブラリのjQueryライブラリを利用して実装してみたいと思います。

jQueryの定義

jQueryの.ajaxを利用するために以下を定義します。
<head>タグ内に以下を記述しましょう。

<script
  src="https://code.jquery.com/jquery-3.7.1.min.js"
  integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
  crossorigin="anonymous"></script>

jQueryのURLは以下のサイトから取得できます。

あわせて読みたい
jQuery
jQuery
  1. 「minified」はコメントや改行などを排除したソースコードで容量が少なく軽量で高速です。
  2. 「uncompressed」は容量が大きいですが、何かエラーが発生した際にデバッグで原因箇所の特定ができます。必要に応じて使い分けてください。

ajaxメソッド

ajaxメソッドでデータを取得する処理を実装してみましょう。

$.ajax({
    url: '/user/123',
    type: 'GET',
    dataType: 'json',
})
.done(function(response) { // リクエストが成功した場合の処理
    appendAlert(response.name,'success')
})
.fail(function(xhr, status, error) { // リクエストが失敗した場合の処理
    if (xhr.status === 0) {
        appendAlert('ネットワークエラーです。','warning')
    } else if (xhr.status === 404) {
        appendAlert('存在しません。','warning')
    }else{
        var responseJSON = xhr.responseJSON;
        if (responseJSON && responseJSON.error) {
            appendAlert(responseJSON.error,'danger');
        }else{
            appendAlert('サーバーエラー:' + error,'danger')
        }
        
    }
})
.always(function() { // 成功・失敗にかかわらず最終的に実行する処理
    console.log('Request complete.');
});

.ajax() は、jQueryライブラリが提供する非同期通信の機能の一つであり、ウェブページとサーバー間でデータの送受信を行う際に利用します。上記の例ではurlの/userに対して「123」のパラメータ付で送信しています。また、実行に成功した場合に、responseから返却があったnameを表示しています。

このように最小限のデータ(今回だとname)をページ全体を再読み込みすることなく取得することができます。

以下が.ajax() メソッドの基本的な機能です。

  1. リクエストの送信先のURLを指定できます。
  2. リクエストのHTTPメソッドを指定できます(GET、POST、PUT、DELETEなど)。
  3. サーバーから返されるデータの形式(JSON、XML、HTML、テキストなど)を指定できます。
  4. サーバーに送信するデータを指定できます(オプション)。
  5. $.ajax() メソッドはPromiseを返し、非同期処理の成功や失敗に応じて、対応するコールバック関数を呼び出すことができます。また、.done(), .fail(), .always()のようなメソッドを使用して、それぞれの状況に応じた処理を簡潔に記述することができます。
ポイント

ネットワークエラーの場合はfailが実行されxhr.statusが0です。

appendAlert関数はBootstrapのアラート機能です。簡単にアラートを表示できるのと成功、警告、エラーのように色分けで表示できる便利機能なので試してみてください!

実行後処理

ajaxを実行した後に.done(), .fail(), .always()を利用して状況に応じた実装が可能です。

成功処理

.done()

.ajax()の処理に成功すると、.done()メソッドに設定したコールバック関数が呼ばれ、第一引数からレスポンスデータを取得できます。
仮にサーバーから以下のように返却された場合、「response.name」にアクセスすると「hebi」が取得できます。

return $this->response->setStatusCode(200)->setJSON(['name' => 'hebi']);
失敗処理

.fail()

ajax()の処理に失敗すると、.fail()メソッドに設定したコールバック関数が呼ばれ、第一引数であるxhrオブジェクトからHTTPステータスコードなどの詳細情報が含まれています。

例としてサーバで以下のようにjsonを返却した場合、xhr.responseJSONから取得することができます。

return $this->response->setStatusCode(500)->setJSON(['error' => 'サーバーエラー']);

第二引数であるstatus引数には次のいずれかの文字列が入ってきます。

  • “timeout”: リクエストがタイムアウトした場合
  • “error”: リクエストがエラーを返した場合
  • “abort”: リクエストが中断された場合

紛らわしいですが第二引数のstatusはHTTPステータスではないことに注意しましょう!

第三引数であるerror引数には例外情報が入ります。上記の例のように500で返却した場合は「Internal Server Error」の値が入ってきました。エラーの内容によって値が変わってきます。

必ず通る処理

.always()

.alwaysメソッドは成功しても失敗に関わらず実行されます。成功失敗で同じ処理を行いたい場合に利用できます。

同期実行

$.ajaxを連続して実行したい場合、非同期のままで実装すると以下のような感じになり、ネスト感が凄く見栄えが悪くなります。

        $.ajax({
            url: '/user/123',
            type: 'GET',
            dataType: 'json',
        })
        .done(function(response) { // リクエストが成功した場合の処理
            // appendAlert(response.name,'success')
            $.ajax({
            url: '/status/123',
            type: 'GET',
            dataType: 'json',
            })
            .done(function(response) { // リクエストが成功した場合の処理
                // appendAlert(response.name,'success')
                
            })
            .fail(function(xhr, status, error) { // リクエストが失敗した場合の処理
                if (xhr.status === 0) {
                    appendAlert('ネットワークエラーです。','warning')
                } else if (xhr.status === 404) {
                    appendAlert('存在しません。','warning')
                }else{
                    var responseJSON = xhr.responseJSON;
                    if (responseJSON && responseJSON.error) {
                        appendAlert(error,'danger');
                    }else{
                        appendAlert('サーバーエラー:' + error,'danger')
                    }
                    
                }
            })
            .always(function() { // 成功・失敗にかかわらず最終的に実行する処理
                console.log('Request complete.');
            });
            
        })
        .fail(function(xhr, status, error) { // リクエストが失敗した場合の処理
            if (xhr.status === 0) {
                appendAlert(error,'warning')
            } else if (xhr.status === 404) {
                appendAlert('存在しません。','warning')
            }else{
                var responseJSON = xhr.responseJSON;
                if (responseJSON && responseJSON.error) {
                    appendAlert(error,'danger');
                }else{
                    appendAlert('サーバーエラー:' + error,'danger')
                }
                
            }
        })
        .always(function() { // 成功・失敗にかかわらず最終的に実行する処理
            console.log('Request complete.');
        });

上記を防ぐために、同期処理に変更して実装しましょう。

    async function getUser() {
        try {
            const response = await $.ajax({
                url: '/user/123',
                type: 'GET',
                dataType: 'json',
            });
            appendAlert(response.name,'success')

            // ここで次に実行したいajaxを実行できる
            const response2 = await $.ajax({
                url: '/status/123',
                type: 'GET',
                dataType: 'json',
            });

            // リクエストが成功した場合の処理
            appendAlert(response2.status,'success')
        } catch (error) {
            if (error.status === 0) {
                appendAlert('ネットワークエラーです。','warning')
            } else if (error.status === 404) {
                appendAlert('存在しません。','warning')
            }else{
                var responseJSON = error.responseJSON;
                if (responseJSON && responseJSON.error) {
                    appendAlert(responseJSON.error,'danger');
                }else{
                    appendAlert('サーバーエラー:' + error.statusText,'danger')
                }   
            }
        }
    } 

$.ajaxメソッドは、Promiseを返すため、try…catchブロックを使用することができます。
$.ajaxの前にawaitを付けることで、処理が完了するまで待機し、完了したら戻り値にレスポンスが返却されます。また、$.ajaxに失敗したらcatchブロックが実行されます。

awaitを利用する際には親関数にasyncを付ける必要がありますのでご注意ください。

最後に

いかがだったでしょうか。Ajaxでデータを取得するシーンは結構あると思います。使い方をマスターしてどんどん使っていきましょう。
Ajaxは非同期通信のため、もし長い処理の場合はスピナー等を表示する必要があるのでご注意ください。

最後までお読みいただきありがとうございました(^^)/

スポンサーリンク
ABOUT ME
hebi
hebi
エンジニア
フルスタックエンジニアとして活躍中。
HTML5プロフェッショナル認定Level1、Level2所持者です。

未経験の方でも簡単にプログラミングを学べるようにと情報を発信しております。
記事URLをコピーしました