なんかサーバーにリクエスト送るの2種類ある?
同期通信と非同期通信??
私が独学でプログラミングを勉強していた時、おそらく最も混乱したポイントです。
同じような経験をされている方、いるんじゃないだろうか?
この記事を書いている私は、
2020年1月現在メガベンチャーの社内スタートアップの部署でエンジニア(1年目)をしてます。
プログラミング未経験からメガベンチャーへの転職を成功させた経験・ノウハウを
ブログにまとめています。
本記事では、「Ajax通信」をソースコード付きで解説します。
「Ajax通信」は、
Progateでは、扱わないトピックです。
そのため理解して使えるようになるのにけっこう時間がかかりました。
ぜひ参考にしてください!
※現在Laravelで実践的なチュートリアルを作成しています。
前回のWebアプリケーション作成記事はこちら
Github:https://github.com/Shuto-san/laravel-vue-docker
Ajax通信とは?
Ajax(Asynchronous JavaScript and XML)は、
JavaScriptでサーバー側と非同期通信を行うための技術になります。
ここでいう「非同期」とは、画面遷移せずにサーバー側と通信できることです。
従来のWebアプリケーションで用いられていたのは、
「同期通信」です。
インターネットを通じて、Webブラウザからサーバーへデータのリクエストを行い、
これに対し、サーバーがWebページデータを返します。
同期通信を用いるとリクエスト毎に画面遷移が発生してしまいます。
その状況に、Ajaxという画面遷移を伴わない非同期通信の技術の登場により、
ストレスない動的なWebアプリケーションを実現できるようになりました。
例えとして有名なのは、GoogleMapです。
画面遷移せずに、マップや店など、様々な情報をリアルタイムで読み取り表示しています。
動的Webアプリケーションは当たり前になっている昨今、
従来のWebアプリケーションは画面遷移を必ず伴うためストレスフルで、
ユーザーに見向きもされません。
したがって現在のWebアプリケーションは、Ajaxを用いるのは必須なのです。
是非本記事で同期通信と非同期通信を実装例とともに理解していきましょう!
同期通信:実装例(リクエスト部分のみ)
html上で以下のように埋め込みます。
一応、GET、POSTリクエスト両方例を載せます
<form action="http://hogehoge.com" method="get">
<label for="say">What greeting do you want to say?</label>
<input name="say" id="say" value="Hi">
<button>Send my greetings</button>
</form>
<form action="http://foo.com" method="post">
<label for="say">What greeting do you want to say?</label>
<input name="say" id="say" value="Hi">
<button>Send my greetings</button>
</div>
</form>
formタグ内のmethodをgetにするかpostにするかの違いです。
サーバー側からのレスポンスは
画面データなので、
サーバーにデータを送るとブラウザの更新部分がグルグルして画面遷移してしまいます。
とても簡単ですね。
ただ、部分的には実装する可能性はゼロではないですが、
この実装方法はあまり実践的ではありません。
現在のWebアプリケーションでは、
基本的に以下で説明する非同期通信を用います。
非同期通信:実装例
いよいよAjaxという技術を用いて、非同期通信の実装例を紹介します!
Ajaxは、jQueryやaxiosなどのライブラリを用いて実装するので、
実装自体はとてもシンプルです。
今回は、axiosを使用します!
アプリの技術スタック、環境はこの記事の設定を用います。
少し実践的に実装を進めます。
<実装内容>
入力フォームに文字を入力
→送信ボタン押下
→Ajaxでサーバー側と通信
→回答を保存する
それでは入力画面、js(Vue):Ajax実装部分、ルーティング、サーバーサイド(PHP/Laravel)の順で実装していきますね。
入力画面
- resources/views/tweet/index.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<link rel="stylesheet" href="{{ mix('/css/tweet.css') }}">
</head>
<body>
<div id="tweet">
<header>
<div class="contents">
<section class="submit-form">
<input v-model="tweet">
<button @click="postTweet">送信</button>
</section>
</div>
</header>
<main>
<div class="contents">
<ul>
@foreach ($tweets as $tweet)
<li>{{ $tweet->tweet }}</li>
@endforeach
</ul>
</div>
</main>
<footer>
</footer>
</div>
<script src="{{ mix('js/tweet.js') }}"></script>
</body>
</html>
フォームへの入力値がサーバー側に送るデータです。
tweetという変数にバインディングされ、jsで使います。
送信ボタンをクリックすると、jsに記述されたpostTweetメソッド
が実行されます。
js(Vue)
- resources/js/tweet.js
require('./csrf.js');
new Vue({
el: '#tweet',
data: {
tweet: ''
},
methods: {
postTweet() {
axios.post('/tweet', {
tweet: this.tweet
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
}
});
axios.post(…
でサーバー側に通信しにいく処理を記述します。
サーバー側のurl(/tweet)とデータ(this.tweet)を設定しています。
then(…
は、レスポンスが返ってきてからの処理
catch(…
は、レスポンスエラー時に実行される処理です。
ルーティング
- routes/web.php
// 入力画面表示
Route::get('/tweet/index', 'TweetController@index');
// ツイート内容保存
Route::post('/tweet', 'TweetController@store');
ルーティングを書いてあげます。
URLに対してなんのコントローラーメソッドを実行するかを記述するところ。
- app/Http/Controllers/TweetController.php
<?php
namespace App\Http\Controllers;
use App\Tweet;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class TweetController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
$tweets = Tweet::all();
return view('tweet.index', compact('tweets'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$user = Auth::user();
$tweet = new Tweet();
$tweet->user_id = $user->id;
$tweet->nickname = $user->name;
$tweet->tweet = $request->tweet;
$tweet->save();
return $tweet;
}
}
axiosを用いたリクエストは、storeメソッドで処理されます。
Authファサードを使えば、
ログインユーザーの情報を引き出すことができます。
tweetsというテーブルにユーザー情報や、送られてきたデータ(tweet)を保存します。
ビルド、実行
jsを作ったのでビルドが必要です。
過去の記事でLaravel Mixにビルド先を記述したのでそこは省略させていただきます。
npm run dev
php artisan serve
ログインしてから、
http://127.0.0.1:8000/login
入力画面にアクセスし、投稿してみましょう!
http://127.0.0.1:8000/tweet/index
まとめ
非同期通信と、同期通信の違い、分かりましたでしょうか?
現在作っているWebアプリケーションに沿って
少し実践的に実装を進めました。
今回はVueで投稿内容を表示する処理を書かなかったので、
動的感は味わえないかもしれませんが、
非同期通信、同期通信の違いや
Ajax通信の実装方法を共有しました。
Ajax、axios、jqueryという単語、非同期通信の概念を押さえれば
何も問題ありません。
インターネットで検索して
自分でも色々実装してみてください!
Ajax通信の存在を理解すれば、
Webアプリケーションエンジニアの第1歩です。
次回は、Laravelでの「バリデーション」と「サービスクラス」を解説していきます!
↓↓
それではまた!
コメント