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); });