Laravel4 POST необъяснимое перенаправление на GET

Я уверен, что еще один вопрос, который я не сделал – не спал. Я отправляю его в жертву Старейшине Богу Мерфи: как только я раскрываю моё недоразумение, чтобы все могли видеть, я гарантированно найду сам тот ответ, который в противном случае ускользнет от меня в течение нескольких часов ( в виде дальнейшей покаяния, Затем я опубликую ответ ).

У меня есть HTML-форма, которая отображается как

<form method="post" id="mysearch" action="/search/?uid=1701"> <input id="searchterm" type="text" name="query" /> </form> 

Форма может быть отправлена ​​через jQuery $.POST с URL-адресом '/ search' и данными { uid: '1701', query: $('#searchterm').val() } и он работает .

Если я нажму ENTER после ввода чего-либо и, таким образом, переопределяю представление jQuery, произойдет следующее:

  • POST выдается серверу, как и ожидалось.
  • Route::post('/search', function() {... не активируется.
  • Возвращается 301 Перемещено навсегда
  • GET с потерянными параметрами поиска выдается URL-адресу, указанному в Redirect
  • Очевидно, что поиск не удался.

Ответ 301 выглядит как-то Laravel4, добавлен явно:

 HTTP/1.0 301 Moved Permanently Date: Thu, 28 Nov 2013 14:05:29 GMT Server: Apache X-Powered-By: PHP/5.4.20 Cache-Control: no-cache Location: http://development/search?uid=1701 Connection: close Content-Type: text/html <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="refresh" content="1;url=http://development/search?uid=1701" /> <title>Redirecting to http://development/search?uid=1701</title> </head> <body> Redirecting to <a href="Redirecting to http://development/search?uid=1701">Redirecting to http://development/search?uid=1701</a> </body> </html> 

Это не то же самое, что и этот вопрос , потому что ожидается перенаправление, и это ответ на нежелательный. Здесь это перенаправление, которое генерируется без причины, на которую я могу (пока) видеть.

Я подозреваю, что по какой-то причине я запускаю «переадресацию безопасности», описанную в этом другом ответе , который не запускается jQuery (либо потому, что он помещает все в POST, тогда как здесь у меня есть один параметр в URL-адресе, а другой в POST или потому, что jQuery использует XHR).

Я думал, что это может быть защита CSRF, но этот конкретный маршрут не защищен. Как последний ресурс, я CSRF-защищаю маршрут и добавляю токен в форму, даже если он немного похож на вуду. Что-то смутно похожее происходит в Rails .

обходные

У меня нет ни одного, ни двух, а трех обходных решений, которые аккуратно обошли бы вопрос о том, почему это происходит:

  • (наиболее жестокие) блокируют событие keyUp в форме.
  • перенаправить событие отправки формы в jQuery
  • (наиболее прозрачный) маршрутизирует указанное событие в $('#search-button').click()

… но я бы хотел сделать без кнопки вообще (что я мог бы сделать с jQuery) и без jQuery вообще . А также понять, что здесь происходит. Я на 99% уверен, что упускаю что-то очевидное.

отладка

Теперь я перейду в grep -r "Redirecting to" * весь исходный код рамки (я ожидаю найти что-то в Symfony/Components/HttpFoundation/ResponseRedirect ) и шаг за шагом оттуда.

Related of "Laravel4 POST необъяснимое перенаправление на GET"

TL; DR

убедитесь, что URL-адреса POST не заканчиваются косой чертой. – но пользователи Laravel 4.1 сначала проверяют обновление ниже.

=======

Когда это работает, это не суеверие – это наука 🙁

как только я разоблачу свое недоумение, чтобы все могли видеть, я гарантированно найду сам тот ответ, который в противном случае ускользал бы от меня

Я буду утверждать, что HTML-сообщение Laravel4 могло быть немного информативным.

grep нашел, как и ожидалось, происхождение переадресации:

 grep -r "Redirecting to" * vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RedirectResponse.php: <title>Redirecting to %1$s</title> vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RedirectResponse.php: Redirecting to <a href="%1$s">%1$s</a>. 

в этот момент простая обратная трасса обнаружила происхождение, очень рано в разрастании Laravel4:

 bootstrap/start.php: ... | The first thing we will do is create a new Laravel application instance | which serves as the "glue" for all the components of Laravel, and is | the IoC container for the system binding all of the various parts. | */ $app = new Illuminate\Foundation\Application; $app->redirectIfTrailingSlash(); 

Как только я увидел redirectIfTrailingSlash , я понял, что два URL-адреса, отправленные формой и jQuery, не совпадают :

 ... action="/search/?uid=1701"> <--- TRAILING SLASH AFTER 'search' ... url: '/search', <--- NO TRAILING SLASH data: { uid : 1701, query: $('#searchterm').val() }, ... 

Почему это должно произойти, я не совсем понимаю, но решение просто ужасно просто:

удалите косую черту из поля действия POST.

(и убедитесь, что .htaccess не имеет правила считать URL-адрес «каталогом» и добавить обратно косую черту, но если бы это было, jQuery тоже не удался).

ОБНОВИТЬ

По-видимому, вопрос был рассмотрен в Laravel 4.1. В обновлении упоминается

Удаление переадресации

В файле bootstrap / start.php удалите вызов $ app-> redirectIfTrailingSlash (). Этот метод больше не нужен, так как эта функция теперь обрабатывается файлом .htaccess, включенным в структуру.

Затем замените файл Apache .htaccess новым, который обрабатывает конечные косые черты.