2016.1.5
0からはじめるPHP#69【Ajax#3-Laravelの遅延ロード-】
ということで
前回動かないと嘆いていたAjax通信が出来たので、まずはそのソースコードを。
Route::group(['middleware' => ['web']], function () {
Route::get('/', 'xxxx');
Route::post('ajax', 'xxxx');
});
なんかいつの間にかルートファイルにこんなルートグループが出来ております。
これに気づかずにずっとハマってました。
このグループの中に入れると、csrf_tokenが発行できるようになります。
変なところからアクセスされないようにpost指定しておくのが良いんじゃないかと思います。
//head内
<meta name="csrf_token" content="{{ csrf_token() }}" />
~~
<div id="aaa"></div>
<input type="button" id="button" value="Hello" />
</form>
<script>
$(document).ready(function(){
$("#button").click(function(){
$.ajax({
url: '{{url("ajax")}}',
type:"POST",
/*ここから*/
beforeSend: function (xhr) {
var token = $('meta[name="csrf_token"]').attr('content');
if (token) {
return xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
},
/*ここまで*/
success: function( data ) {
jQuery("#aaa").append(data);
},
error: function() {
alert("error");
}
});
});
});
</script>
で、500エラーって一体なんなのかっていうと、ずばり
MethodNotAllowedHttpExceptionなんですね。つまりトークンです。
ということは、そのトークンを何とかして読み込み先のページに渡せば問題は解決するはずです。では、一体どうしたら良いのでしょう。
まず、ヘッダーにトークンを埋め込みます。
で、beforeSend内でそのトークンをtokenに読み込むわけですね。attrメソッドについては
こちらがわかりやすいと思いますが、今回はmetaタグのcontentの値を持ってきてるわけですね。
で、xhrのヘッダーにLaravelが読み込めるようにトークンの値を設定してるんですかね?
正直この辺はよく分かんないです。
ただ、xhrというのは
非同期なデータの通信を実現するためのAPIでして、つまりこいつがHTTPのような振る舞いを見せることで、そのヘッダーに予想されたトークンが存在していた場合通信を許可する・・・・・・といった流れになってるんじゃないかなあと予測しています。
ちょっと具体的な挙動を調べても仕方がないというか、jQueryの勉強はもっと後になってから良いかなと思うので、今はまず動くものから作ろうかなと思います。ということで分かんないとこはスルー。(笑)
で、データの送受信が上手く行ったら、帰ってきたデータをdiv#aaaにappendするわけです。
これでLaravelのシステムにAjax非同期通信が組み込めることが分かったので、これを使えば良いことになりますね。
必要なデータ、例えば現時点で取得している時間とかなどなどをこちらでdataとして送信すれば良いわけですね。
そして、データベースからデータを取ってくる作業はphpファイルで隠蔽化するわけです。
ちなみに、クエリービルダーで指定した件数を飛ばしたり、部分だけ取得するには
skip/takeメソッドを使うとのことです。
ただ、遅延ロードの間に新しい投稿がされる場合もあるので、基本的には最終取得IDから逆算しての表示になりそうです。
(時間だと秒単位なので被る場合があって処理できない)
つまり、取得したIDをjavascript側に渡して、そのIDより小さいデータ
(つまり古いデータ)をWHERE句で持ってきて、そこからtakeで部分だけ取り、その最後のIDをjavascript側に送信して記憶させる・・・・・・といった流れになりそうです。
発言番号のIDなんて漏れたところでさして痛くも痒くもないので、これは別に隠蔽する必要ないですね。
コーディングの話に関してはこれである程度出揃った感があるんで
(そうなんです、出揃ってるんですよ)次回はついにシステムについての話に触れてみたいなと思っています。