コミュニティ

初心者目線でAjaxの説明

この記事は最終更新日から1年以上が経過しています。

Ajaxとは

Ajaxとは「Asynchronous JavaScript + XML」の略

Asynchronousとは、非同時性の、非同期の

つまり、「JavaScriptとXMLを使って非同期にサーバとの間の通信を行うこと。」

んん?
詳しく内容を追っていきましょう。

そもそも非同期通信とはどんなものか?

ajax_example.gif

このように画像の遷移のない通信を非同期通信と言います。
同期処理は一瞬画面が白くなって、画面を切り替わることを言います。

こういったことをするためにAjaxという仕組みが必要です。

どうしてこんなことができるのか?

大枠をざっくり先に説明します。

同期通信の場合

webブラウザからサーバーにリクエストを通信し、レスポンスが戻ってくる。
この時に、すべての情報を通信しているので、一瞬画面が白くなる。
=>サーバーからレスポンスが返ってくるまでは他の作業はできない。

非同期通信の場合

webプラウザから一部の情報をリクエストするので、
それ以外の部分は変わらない。なので画面が白くなることがない。
=>サーバーからレスポンスが返ってこなくても他の作業ができる。

ほー
ってことは一部の情報をサーバーに送信して、それを受け取り反映させる仕組みをAjaxっていうんだね。

でもどうやってやっているの?

Ajaxを支える仕組み

ここで登場する技術が

  • XMLHttpRequest
  • JavaScript
  • DOM
  • XML

Ajaxというのは一つの機能でできているのではなく、
複数の機能が組み合わさって実装しています。

それぞれ機能を見ていきましょう

XMLHttpRequest

クライアントとサーバーの間でデータを伝送するための機能をクライアント側で提供する API です。
ページ全体を再読み込みすることなく、URLからデータを読み出す簡単な方法を提供します。
このAPIによって、ユーザの作業を中断させることなくWebページの一部を更新することができます。
(MDNより)

要するに、ブラウザ上でサーバーとHTTP通信を行うためのAPIです。

このAPIを使って実装をするのがJavaScriptです。
でもなんでJavaScriptなの?

JavaScript

それは先程のXMLHttpRequestがjavascriptの組み込みオブジェクトだからです。
組み込みオブジェクトとは、あらかじめ定義されているオブジェクトのことですね。

Ajaxという名前にある通り、非同期通信はjavascriptを使わないと実装できないのです。

DOM

Document Object Model (DOM) は、HTML および XML ドキュメントのための API です。これはドキュメントの構造的な表現を提供し、内容や表示形態の変更を可能にします。端的に言えば、Web ページをスクリプトやプログラミング言語とつなぐような機構です。
(MDNより)

つまり、Ajaxを使って動的なWebページを作成するときに、HTML・XML上のどの要素を変更するかを指定します。そこでDOMはHTMLやXMLを「ツリー構造」として展開し、アプリケーション側に文章の情報を伝え、加工や変更をしやすくするものです。

ツリー構造とは、データ構造の一つで、一つの要素(ノード)が複数の子要素を持ち、一つの子要素が複数の孫要素を持ち、という形で階層が深くなるほど枝分かれしていく構造のこと。

ここで出てくるXMLとはなんなのでしょうか?

XML

Extensible Markup Languageの略。
文書やデータの意味や構造を記述するためのマークアップ言語の一つ(HTMLと似たようなもの)

<?xml version="1.0" encoding="Shift_JIS"?>
<?xml-stylesheet type="text/xsl" href="testxsl.xsl"?>
<おこづかい帳>
 <支出>
  <内容>
   <日付>1月20日</日付>
   <交通費>780</交通費>
   <食費>980</食費>
   <嗜好品>250</嗜好品>
  </内容>
  <内容>
   <日付>1月21日</日付>
   <交通費>950</交通費>
   <食費>1200</食費>
   <嗜好品>300</嗜好品>
  </内容>
  <内容>
   <日付>1月22日</日付>
   <交通費>500</交通費>
   <食費>1500</食費>
   <嗜好品>250</嗜好品>
  </内容>
 </支出>
</おこづかい帳>

XMLはタグを自由に設定でき、そのタグに意味づけをすることができます。

データのやりとりで「XML」を使えば、複数のデータを同時にやりとりしても、どのデータがどの要素なのか一発で判明できます。

ただ現在では、AjaxにはXMLの代わりにJSONという型がよく使われています。
Ajaxという名前にXMLが入っているので、他の型は使えないように思いますが、
そうではないんですね。

Json

JavaScript Object Notationの略。
軽量のデータ交換フォーマットで、人間にとって読み書きが容易で、マシンにとっても簡単にパースや生成を行なえる形式です。

{ "name"   : "John Smith",
  "sku"    : "20223",
  "price"  : 23.95,
  "shipTo" : { "name" : "Jane Smith",
               "address" : "123 Maple Street",
               "city" : "Pretendville",
               "state" : "NY",
               "zip"   : "12345" },
  "billTo" : { "name" : "John Smith",
               "address" : "123 Maple Street",
               "city" : "Pretendville",
               "state" : "NY",
               "zip"   : "12345" }
}

現在ではJSONを使用して、非同期通信を行うのが主流となっています。

ん〜
なんだか色々な言葉が出てきたので、まとめて欲しいな〜

まとめ(流れの整理)

ここまで説明してきたものが、どのように関係して、
Ajaxの機能を実装しているかをまとめます。

unnamed.jpg

①ページ上で任意のイベントが発生(ボタンクリックなど)

②JavaScript + XMLHttpRequestでサーバーに対してリクエストを送信(非同期通信)

ほしい情報、返ってくるレスポンスの情報を指定してリクエスト

③サーバーで受け取った情報を処理

サーバーの処理中もクライアントは操作を継続できる

④処理結果をJSONやXMLなどの形式で応答

⑤受診したレスポンスを受けて、DOMでページを更新

更新のあった部分だけを書き換えるため、画像が一瞬白くなることはない。
 
このように機能が結びついてAjax機能を実装しているんですね。

サンプルアプリで動きの確認

abc.gif

文字を入力したらその文字が表示されるアプリを通してAjaxを確認してみます

index.html.erb
<div class="contents">
  <%= form_for @todo, html: { class: 'form js-form' } do |f|%>
    <%= f.text_field :content, class: 'form__text-field js-form__text-field' %>
    <%= f.submit class: 'form__submit js-submit' %>
  <% end %>
  <ul class="todos">
    <%= render @todos %>
  </ul>
</div>

_todo.html.erb
<li class="todo"><%= todo.content %></li>
todos.controller.rb
class TodosController < ApplicationController

  #indexアクションはTodoの一覧ページとTodoの入力ページを兼ねているので、新しいTodoを作成するためのインスタンスと、テーブルに保存されているTodoを取得します。
  def index
    @todo = Todo.new
    @todos = Todo.order('created_at ASC')
  end

#createアクションが呼ばれると何かしらのTodoが入力されていた場合(contentが空でない場合)は、Todoを保存しTodoの一覧ページにリダイレクトします。反対にTodoが入力されていない場合(contentが空の場合)は、Todoの保存はせずに、Todoの一覧ページを再描画します。
  def create
    @todo = Todo.new(todo_params)
    if @todo.save
      respond_to do |format|
        format.html { redierct_to :root }
        format.json { render json: @todo}
      end
    else
      render :index, alert: 'Todoを入力してください'
    end
  end
#respond_to doを使用し、リクエストされたformatによって処理を分けるようにします。今回はhtmlと非同期通信のためのjsonを扱うようにしました。フォーマットがjsonの時の説明をします。この後jsファイル側で作成したtodo(@todo)を使用するためにrenderメソッドを使用し、作成したtodoをjson形式で返すようにします。

  private
  def todo_params
    params.require(:todo).permit(:content)
  end
end

todo.js
$(function() {
  function buildHTML(todo) {
    //以下はセレクタの中身を新規に作るという意味
    var html = $('<li class="todo">').append(todo.content);
    return html;
  }
//submitイベントを使い、フォーム(js-from)が送信された時に処理が実行されるようにイベントを設定。
  $('.js-form').on('submit', function(e) {
    e.preventDefault(); //フォームが送信された時に、デフォルトだとフォームを送信するための通信がされてしまうので、preventDefault()を使用してデフォルトのイベントを止めます。
    var textField = $('.js-form__text-field'); //class js-form__text-fieldを代入
    var todo = textField.val(); //js-form__text-fieldのフォームに入力された値を取得し、todoに代入
    //$.ajax関数は、戻り値として XMLHttpRequestオブジェクトを返します。
    //ここでサーバーに対しての通信を行う。情報の指定(ここではdataに格納)、送信先、データの型(Json)等を記述
    $.ajax({
      type: 'POST',
      url: '/todos.json',
      data: {
        todo: {
          content: todo
        }
      },
      dataType: 'json' //データをjson形式で飛ばす
    })
    //↓フォームの送信に成功した場合の処理
    .done(function(data) {
      var html = buildHTML(data);
      $('.todos').append(html); //$.append関数は操作後はDOMに要素が追加された状態になる。
                                                                 //todosクラスに引数で指定したdataのHTML要素を追加。

      textField.val(''); //
    })
    //↓フォームの送信に失敗した場合の処理
    .fail(function() {
      alert('error');
    });
  });
});

以上の流れでAjax機能が動いています。
すごい仕組みだな〜

hisamura333
crowdworks
21世紀の新しいワークスタイルを提供する日本最大級のクラウドソーシング「クラウドワークス」のエンジニアチームです!
https://crowdworks.co.jp/
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
コメント

2箇所だけ「ブラウザ」が「プラウザ」になっている部分があります。

Ajaxと非同期通信を理解するのにとても苦戦していたのですが、
すごく簡単に理解する事ができました!
ありがとうございます‼︎

あなたもコメントしてみませんか :)
すでにアカウントを持っている方は
ユーザーは見つかりませんでした