Я кодирую аукционный веб-сайт в 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, поэтому я не отправлял токены _ с моими 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 — Почему я начал получать единичное исключение TokenMismatchException, когда я включил промежуточное программное обеспечение VerifyCsrfToken в kernel.php, если я начал отправлять _token со своими AJAX-запросами?
3 — Почему X-CSRF-TOKEN окончательно решил проблему с ошибкой HTTP 500? Имейте в виду, что все ошибки были спорадическими и не постоянными: я рискнул бы сказать, что 95-98% всех запросов AJAX выполнялись нормально, только у небольшого числа из них были какие-либо проблемы.
Других решений пока нет …