LaravelでPOSTしてもControllerが呼び出されなくて、ちょっとハマった話。
route/web.phpには、きちんと書いてある。
Route::post('/hoge', 'IndexController@post')->name('index.post');
Controllerでは、呼び出されたらログを出力するようにしておく。
public function post(Request $request)
{
\Log::debug('IndexController@post');
\Log::debug($request);
return redirect()->route('top');
}
bladeにformを作成する。
<form method="post" action="{{ route('index.post') }}">
<input type="text" name="hoge" />
<input type="submit" value="送信" />
</form>
これで動かしてみても、storage/logs/laravel.log に IndexController@post でログ出力しているはずが、何も残らない。
なぜっ!!
route/web.php にgetメソッドでのアクセスも追加してみた。
Route::post('/hoge', 'IndexController@post')->name('index.post');
Route::get('/hoge', 'IndexController@post')->name('index.post');
ブラウザでURLを直接指定してアクセスしてみたら、ログに出力された。
getでは動くのに、postでは動かない。
はて?
しばらく考えて気付いた。
@csrfを書き忘れていた。
<form method="post" action="{{ route('index.post') }}">
@csrf
<input type="text" name="hoge" />
<input type="submit" value="送信" />
</form>
これで無事に post が動くようになった。
Ajaxでpostしようとするときにも忘れがち。
まず、headタグ内にCSRFトークンを用意しておく。
<meta name="csrf-token" content="{{ csrf_token() }}">
で、Ajax部分はこちら。
これを書いとかないとpostが動いたように見せかけて動いてない。
let url = 'hoge';
let data = 'hoge';
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: url,
method: 'post',
data: data,
})
.then(function(data) {
console.log(data);
});
