Share on

複雑なAjaxで悩みがち!処理をうまく解決する3つの方法

複雑なAjaxで悩みがち!処理をうまく解決する3つの方法

Webサイトでエリアを絞るとき等、通常はリンクでページ遷移しますが、ページを読み込む待ち時間がプチストレス…
そんなときにページ全体の読み込みをしないで、非同期通信(Ajax)でページ内のコンテンツを一部だけ更新・生成することができます。

今回はAjaxのご紹介と実装方法を解説します。

非同期通信とは?

非同期通信のイメージ

非同期通信とは、ブラウザの操作が行える通信のことです。
Webページは、ブラウザがサーバーからページの情報をもらうことで表示を行っています。このブラウザとサーバーのやり取りを通信と呼んでいます。

基本的には、通信が行われているときは、画面全体の更新が発生して、ブラウザ操作を行うことができません。非同期通信では例外的にブラウザ操作を行える状態で、データベースや外部ファイルからデータを取得して、一部の画面を更新できます。

またWebサイトを扱っていると、非同期通信と聞くと、Ajaxと連想する方も多いと思います。Ajaxとは、JavaScriptを扱った非同期通信のことです。

レガシー&モダンな2種類のAjax実装について

2種類のAjaxのメリット・デメリット

Ajaxを行う方法はいくつもありますが、jQueryとaxiosを使った2種類の実装を、メリット・デメリットを含め、ご紹介します。

jQueryを使ったAjaxについて

jQueryを使うことで、JavaScriptの機能を、わかりやすい記述で実装できるようになります。jQueryを扱ったAjaxは、レガシーな記述方法です。
こちらのCDNからファイルを読み込むことで、jQueryを扱うことができます。

メリット

どのブラウザにも対応しており、Internet Explorerで動作しないという心配がありません。またWebサイトを扱っていると馴染み深いjQueryのため、導入しやすいです。

デメリット

複数の非同期通信を行ったとき、処理が複雑になってしまいます。そのため複数の非同期通信の場合は、後述するaxiosを使うことを推奨します。

もしjQueryのみで行う場合は、「$.Deferred」や 「$.when」といったjQueryの機能を使うと、複雑化を避けやすいです。こちらの記述方法は、後ほど記載します。

axiosを使ったAjaxについて

axiosを使うことで、JavaScriptの機能を、わかりやすい記述で実装できるようになります。axiosを扱ったAjaxは、モダンな記述方法になります。

下記を読み込むことで、axiosを扱うことができます。

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

メリット

シンプルな記述で、複数の非同期通信も、わかりやすく書くことができます。フレームワークと組み合わせて使われていることも多く、Internet Explorerとの兼ね合いもありますが、ライブラリを読み込んでもいい環境なら、axiosを使うのが推奨です。

デメリット

インターネットに上がっている多くのソースは、axiosを使っている場合、Internet Explorerで動作しない記述方法です。理由は、多くの記事は、モダンな記述方法で書かれているためです。

全てに対応できるわけではありませんが、axiosを使ったInternet Explorerに対応させるための方法も、後ほどご紹介します。

実装方法が異なる3つの状況

実装が変わる3つの状況

2種類のAJAX実装についてご説明しました。どちらで実装したとしても、状況によって実装方法が異なります。実装方法が違う3つの状況について説明します。

非同期通信を1回だけ行って、画面へ反映するとき

1つ目の状況は、非同期通信を1回だけ行ったときの実装方法です。
例えば「フォームから応募を行ったユーザー一覧」の外部ファイルを、1回だけ取得して、画面へ反映するときです。

複数の非同期通信を全て読み込んだ後に、画面へ反映するとき

2つ目の状況は、複数の非同期通信を全て読み込んだときの実装方法です。
例えば「フォームから応募を行ったユーザー一覧」の外部ファイルが複数あるとします。そのファイルを全て読み込んだ後に、画面へ反映するときです。

複数の非同期通信を1つずつ処理して、画面へ反映するとき

3つ目の状況は、複数の非同期通信を、1つずつ読み込んでいくときの実装方法です。
例えば「フォームから応募を行ったユーザー一覧」の外部ファイルが複数あるとします。そのファイルを1つ読み込み、読み込んだデータを使って、次の非同期通信へデータを渡したいときです。

この3つの状況によって実装方法が異なりますので、それぞれの状況に合わせてご紹介します。

Ajaxの実装方法

それではjQueryとaxiosのソースを、3つの状況に合わせて掲載します。掲載するソースは、jQuery・axiosどちらも同じ動作になります。HTMLのソースは共通、JavaScriptのソースは一部共通です。jQueryとaxiosを使った箇所の記述が異なります。

HTML (jQuery・ axiosどちらにも入る共通処理)

<div id="list"><ul class="list-group"></ul></div>
<div id="error"></div>

JavaScript (jQuery,・axiosどちらにも入る共通処理)

// 画面を更新する処理
function appendList(data) {
    $.each(data, function(num, data) {
        $('#list ul').append('
  • ' + "名前:" + data.name + "
    年齢:" + data.age + '
  • '); }); } // エラー処理 function error(error) { $('#list').empty(); $('#error').append(error); }

    jQueryを使ったAjaxの記述方法

    非同期通信を1回だけ行って、画面へ反映するとき

    var jqueryParam = {
        type: "POST",
        url: "doc/sample.json",
        dataType: 'json'
    };
    
    $.ajax(jqueryParam)
    .done(function (data, testStatus, jqXHR) {
        appendList(data.forms);
    })
    .fail(function (jqXHR, textStatus, errorThrown) {
        error(jqXHR.responseText);
    });
    

    複数の非同期通信を全て読み込んだ後に、画面へ反映するとき

    var jqueryParam = {
        type: "POST",
        url: "doc/sample.json",
        dataType: 'json'
    };
    
    var jqueryParam2 = {
        type: "POST",
        url: "doc/sample2.json",
        dataType: 'json'
    };
    
    var jqueryParam3 = {
        type: "POST",
        url: "doc/sample3.json",
        dataType: 'json'
    };
    
    $.when(
        $.ajax(jqueryParam),
        $.ajax(jqueryParam2),
        $.ajax(jqueryParam3)
    )
    .done(function (res1, res2, res3) {
      var sample1 = {
        data: res1[0],
        testStatus: res1[1],
        jqXHR: res1[2]
      };
      var sample2 = {
        data: res2[0],
        testStatus: res2[1],
        jqXHR: res2[2]
      };
      var sample3 = {
        data: res3[0],
        testStatus: res3[1],
        jqXHR: res3[2]
      };
    
      appendList(sample1.data.forms);
      appendList(sample2.data.forms);
      appendList(sample3.data.forms);
    })
    .fail(function (jqXHR, textStatus, errorThrown) {
        error(jqXHR.responseText);
    });
    

    複数の非同期通信を1つずつ処理して、画面へ反映するとき

    var jqueryParam = {
        type: "POST",
        url: "doc/sample.json",
        dataType: 'json'
    };
    
    var jqueryParam2 = {
        type: "POST",
        url: "doc/sample2.json",
        dataType: 'json'
    };
    
    var jqueryParam3 = {
        type: "POST",
        url: "doc/sample3.json",
        dataType: 'json'
    };
    
    function sample(param) {
        var deferred = $.Deferred();
        $.ajax(param).done(function(data, testStatus, jqXHR) {
            appendList(data.forms);
            deferred.resolve();
        }).fail(function(jqXHR, textStatus, errorThrown) {
            deferred.reject(jqXHR.responseText);
        });
        return deferred.promise();
    };
    
    sample(jqueryParam)
    .then(sample(jqueryParam2), error)
    .then(sample(jqueryParam3), error);
    

    axiosを使ったAjaxの記述方法

    非同期通信を1回だけ行って、画面へ反映するとき

    axios.post("doc/sample.json")
    .then(response => {
        appendList(response.data.forms);
    })
    .catch(error => {
        window.error(error.response.data);
    });
    

    複数の非同期通信を全て読み込んだ後に、画面へ反映するとき

    var urls = ["doc/sample.json", "doc/sample2.json", "doc/sample3.json"];
    Promise.all(
        urls.map(url => axios.post(url))
    )
    .then(([sample,sample2, sample3]) => {
        appendList(sample.data.forms);
        appendList(sample2.data.forms);
        appendList(sample3.data.forms);
    })
    .catch(error => {
        window.error(error.response.data);
    });
    

    複数の非同期通信を1つずつ処理して、画面へ反映するとき

    axios.post("doc/sample.json")
    .then(response => {
        appendList(response.data.forms);
        return axios.post("doc/sample2.json");
    })
    .then(response => {
        appendList(response.data.forms);
        return axios.post("doc/sample3.json");
    })
    .then(response => {
        appendList(response.data.forms);
    })
    .catch(error => {
        window.error(error.response.data);
    });
    

    エンジニアじゃないとソースを見ても難しいと思いますが、ぱっと見てもaxiosは記述量が少なく、可視性も高いです。
    複数の非同期通信に関して、jQueryは、「$.Deferred」や 「$.when」を使ってできる限りわかりやすく記述していますが、それでもaxiosのほうが簡潔です。このソースはシンプルな処理ですが、複雑な処理になると、記述量はさらに変わります。

    記述量が多くわかりづらいと、記述ミスにも繋がり、修正にも時間がかかってしまいます。そのため、複数の非同期通信や複雑な処理の場合は、axios推奨。

    モダンな記述をInternet Explorerへ対応させる方法

    掲載したaxiosのソースは、モダンな記述方法のためInternet Explorerに対応していません。こちらをInternet Explorerでも読み込めるようにするには、2つやることがあります。

    1つ目は、下記を読み込むことです。
    読み込むことで、モダンな機能を動作させることができるようになります。

    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6"></script>
    

    2つ目は、Babelを使うことです。
    Babelは、モダンな記述を、旧ブラウザでも読めるソースへ変換できます。
    Webページから、Babelを使うことができますので、ご紹介します。

    こちらへアクセスして、上部タブの「Try it out」のページへ行きます。TARGETSというテキストエリアをdefaultsのみにします。
    次に、左右にソースがありますので、左側に変換したいソースを張り付けると、右側に旧ブラウザでも読み込めるソースを生成します。

    このように変換を行うことができますが、注意も必要です。

    • 全ての記述を上手く変換できるわけではありません
    • 変換すると、ソースの量が多くなってしまう場合があります

    Internet Explorer を対応させるには、jQueryを使うか、Babelを使うかの選択肢がありますので、状況に応じて制作を行いましょう。

    まとめ

    • Ajaxは、3つの状況によって実装方法が異なる
    • InternetExplorer非対応の場合、axios推奨
    • InternetExplorer対応の場合、jQueryかbabelで実装できる

    案件の要件と状況によって、よりよい実装方法を選択できればいいですね。開発に入る前に決められると、工数も削減できると思います。非同期通信というと難しいイメージもあるかもしれませんが、状況に応じた実装を覚えて使っていきましょう。

    クーシーブログ編集部

    この記事を書いた人

    クーシーブログ編集部

    1999年に設立したweb制作会社。「ラスクル」「SUUMO」「スタディサプリ」など様々なサービスの立ち上げを支援。10,000ページ以上の大規模サイトの制作・運用や、年間約600件以上のプロジェクトに従事。クーシーブログ編集部では、数々のプロジェクトを成功に導いたメンバーが、Web制作・Webサービスに関するノウハウやハウツーを発信中。

    お問い合わせはこちらから

    Web制作デザイン、丸ごとお任せ

    お問い合わせする

    Share on

    お問い合わせはこちら

    CATEGORY LIST