Я кодирую сайт аукциона в Laravel 5.0, который имитирует обновления в реальном времени с использованием опроса AJAX, который выполняется каждые 5 секунд. Проблема в том, что мой сервер возвращает спорадический статус HTTP 401.
Мой маршрут построен следующим образом:
Route::post(auction/live/update, 'AuctionController@ajaxSendUpdate');
Мой контроллер выглядит так:
public function ajaxSendUpdate() { // Business logic: queries database, couple of Ifs, etc… $data = array('success' => true, 'otherStuff' => $myData); return Response::json($data); }
Наконец, мой опроллер настроен следующим образом:
// a bit of HTML function getAuctionUpdate() { setTimeout(function () { $.ajax({ type: "POST", url: "{!! url('auction/live/update')!!}", dataType: 'json', data: { auctionID: $('#auctionID').val() }, success: function (data) { if (data['success']) { // Updates some labels, etc. getAuctionUpdate(); // Rearms itself } } } }); // Not sure if all brackets are correct in this snippet but they are 100% on real code }, 5000);
Этот код работает нормально около 95% раз. Однако это может сломаться с двумя разными результатами:
1) Сервер реагирует на ошибку 401 через некоторое время и никогда не восстанавливается. В этом случае нам нужно снова войти в систему. После входа в систему все идет хорошо, и этот результат никогда не повторится.
2) Сервер отвечает спорадическим 401, но восстанавливается в следующих (или после нескольких) запросах на опрос.
Я использую Laravel 5.0 и обновленную версию Xampp в Windows. Ошибка легко воспроизводится с помощью WAMP в Windows. Не тестировалось в Linux и OSX. Я прочитал этот и этот и отсортированные темы в laracasts.com и других форумах, но я не могу решить проблему …
После многих часов тестирования я считаю, что решил эту проблему, даже если я не совсем понимаю, как и даже если это универсальный ответ, который можно применить к аналогичным случаям.
В начале разработки у меня было промежуточное ПО VerifyCsrfToken, отключенное в kernel.php, поэтому я не отправлял _token с моими запросами AJAX. Включение промежуточного ПО VerifyCsrfToken и отправка _token немедленно заставили ошибки HTTP 401 исчезнуть. Теперь у меня возникла другая проблема: еще более спорадические ошибки HTTP 500. Быстрый взгляд на журналы показал, что все ошибки HTTP 500 были вызваны TokenMismatchException.
Затем я наткнулся на это . Следуя инструкциям веб-страницы, я поместил это в свой заголовок master.page:
<meta name="csrf-token" content="{{ csrf_token() }}">
И это на моем master.page javascript:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
И как-то все хорошо. Итак, для всех целей и задач моя оригинальная проблема решена, но я все еще не могу понять:
1 – Почему я получал спорадические ошибки HTTP 401, когда я не отправлял какие-либо _token с моими запросами AJAX, если у меня было проверено промежуточное ПО VerifyCsrfToken в kernel.php?
2 – Почему я начал получать sporadic TokenMismatchException, когда я включил промежуточное программное обеспечение VerifyCsrfToken в kernel.php, если я начал отправлять _token с моими запросами AJAX?
3 – Почему X-CSRF-TOKEN, наконец, решила проблему с ошибкой HTTP 500? Имейте в виду, что все ошибки были спорадическими и не постоянными: я бы рискнул сказать, что от 95 до 98% всех запросов AJAX пошли хорошо, только у небольшого числа из них была какая-то проблема.