Laravel4 POST无法解释重定向到GET

我确信,另一个我没有睡觉的问题。 我把它作为牺牲给老上帝墨菲发布:一旦我揭露了我的所有人看到的蠢事,我保证会自己找到答案,否则我将躲过几个小时( 通过进一步的忏悔,然后我会发布答案 )。

我有一个HTML表单,呈现为

表单可以通过jQuery $.POST提交,其中url为’/ search’,数据为{ uid: '1701', query: $('#searchterm').val() } 并且可以正常工作

如果我在输入内容后按ENTER键,从而覆盖jQuery提交,则会发生以下情况:

  • 按预期方式向服务器发出POST。
  • Route::post('/search', function() {...不会被调用。
  • a返回301 Moved Permanently
  • 搜索参数丢失的GET发布到重定向指定的URL
  • 很明显,搜索失败了。

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      Redirecting to http://development/search?uid=1701   Redirecting to Redirecting to http://development/search?uid=1701   

这与此问题不同 ,因为预期会出现重定向这是不希望出现的问题的答案。 这是重定向本身,无缘无故地生成(现在)。

我怀疑由于某种原因我触发了另一个答案中描述的“安全重定向”, 这不是由jQuery触发的(因为它将所有内容放在POST中,而在这里我在URL中有一个参数而另一个在POST,或者因为jQuery使用XHR)。

我原以为它可能是一个CSRF防御,但是那个特定的路线没有被屏蔽。 作为最后一个资源,我将CSRF保护路由并将令牌添加到表单中,即使它看起来有点像伏都教给我。 Rails中似乎发生了一些模糊相似的东西。

解决方法

我没有一个,而不是两个,而是三个解决方案,巧妙地回避了上述问题的原因

  • (最残酷的)阻止表单中的keyUp事件。
  • 将表单的submit事件重定向到jQuery
  • (最透明)将上述事件路由到$('#search-button').click()

…但我想完全没有按钮(我可以用jQuery做)并且完全没有jQuery 。 同时了解这里发生了什么。 我99%肯定我错过了一些明显的东西。

调试

我现在要grep -r "Redirecting to" *整个框架源代码(我期望在Symfony/Components/HttpFoundation/ResponseRedirect找到一些东西)并从那里一步一步地进行。

TL; DR

确保POST URL不以斜杠结尾。 – 但是Laravel 4.1用户首先检查下面的更新。

=======

它工作时,它不是迷信 – 这是科学 🙁

一旦我揭露了我的所有人的蠢货,我保证会自己找到答案,否则我将无法回答几个小时

我认为Laravel4的HTML消息本来可以提供更多信息。

grep按预期找到重定向的来源:

 grep -r "Redirecting to" * vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RedirectResponse.php: Redirecting to https://stackoverflow.com/questions/20268863/laravel4-post-unexplained-redirect-to-get/%1$s vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/RedirectResponse.php: Redirecting to https://stackoverflow.com/questions/20268863/laravel4-post-unexplained-redirect-to-get/%1$s. 

在那一点上,一个简单的回溯找到了起源,在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 ,我意识到表单和jQuery发送的两个URL 不一样

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

为什么会发生这种情况我不太了解,但解决方案非常简单:

从POST操作字段中删除斜杠。

(并确保.htaccess没有规则将URL视为“目录”并添加斜杠 - 但如果有,则jQuery也会失败)。

UPDATE

显然,这个问题在Laravel 4.1中得到了回顾。 升级提到

删除重定向尾随斜杠

在bootstrap / start.php文件中,删除对$ app-> redirectIfTrailingSlash()的调用。 不再需要此方法,因为此function现在由框架中包含的.htaccess文件处理。

接下来,用这个处理尾部斜杠的新文件替换你的Apache .htaccess文件。