Laravel4 POST无法解释的重定向到GET [英] Laravel4 POST unexplained redirect to GET

查看:69
本文介绍了Laravel4 POST无法解释的重定向到GET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我敢肯定,还有一个我没有睡觉的问题.我将其作为对长老墨菲的牺牲:一旦我公开了对所有人的宽恕,我便保证自己寻找答案,否则我将被躲避数小时. (为了进一步ance悔,我也将发布答案.)

Another I-did-not-sleep-enough question, I'm sure. I'm posting it as a sacrifice to the Elder God Murphy: as soon as I expose my moronity for all to see, I'm guaranteed to find by myself that answer that otherwise will elude me for hours (by way of further penance, I will then post the answer as well).

我有一个HTML表单,显示为

I have a HTML form that gets rendered as

<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() } 提交 .

The form can be submitted via jQuery $.POST with url of '/search' and data of { uid: '1701', query: $('#searchterm').val() } and it works.

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

If I press ENTER after entering something, and thus override the jQuery submission, the following happens:

  • 按预期方式将POST发布到服务器.
  • Route::post('/search', function() {...不会被调用.
  • 返回永久移动的301
  • GET
  • a POST is issued to the server, as expected.
  • the Route::post('/search', function() {... does not get invoked.
  • a 301 Moved Permanently is returned
  • a GET with search parameters lost is issued to the URL specified by the Redirect
  • quite obviously, the search fails.

301响应看起来像Laravel4一样,明确添加:

The 301 response looks like something by Laravel4, added explicitly:

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>

这与此问题不同,因为那里是预期的重定向,而这是对那个的不希望的答案.这里是重定向本身,它是出于我现在(现在)看不到的原因而生成的.

This is not the same as this question, because there the redirect is expected and it's the answer to that which is undesired. Here it's the redirect itself that is generated for no reason that I can (for now) see.

我怀疑出于某种原因,我正在触发

I suspect that for some reason I'm triggering the "security redirect" described in this other answer, that is not triggered by jQuery (either because it puts everything in the POST while here I've one parameter in the URL and another in the POST, or because jQuery uses XHR).

我曾经以为这可能是CSRF防御,但是该特定路线并未被屏蔽.作为最后的资源,我将对路径进行CSRF保护,并将令牌添加到表单中,即使它对我来说看起来像是伏都教. Rails 中似乎发生了一些类似的事情.

I had thought it might be a CSRF defense, but that particular route isn't shielded. As a last resource, I'll CSRF-protect the route and add the token to the form, even if it looks a bit like voodoo to me. Something vaguely similar appears to be happening in Rails.

我没有一个,不是两个,而是三个变通方法,可以巧妙地避开为什么的问题是上述情况:

I've got not one, not two, but three workarounds that neatly sidestep the question of why is the above happening:

  • (最残酷的)阻止表单中的keyUp事件.
  • 将表单的 submit 事件重定向到jQuery
  • (最透明)将上述事件路由到$('#search-button').click()
  • (most brutal) block the keyUp event in the form.
  • redirect the submit event of the form to jQuery
  • (most transparent) route the above event to $('#search-button').click()

...但是我想完全不使用按钮(我可以使用jQuery)和完全不使用jQuery .还要了解这里发生了什么.我99%可以肯定我遗漏了一些明显的东西.

...but I'd like to make without the button altogether (which I could do with jQuery) and without jQuery altogether. As well as understand what is happening here. I'm 99% certain I'm missing something obvious.

我现在要遍历整个框架的源代码(我希望在Symfony/Components/HttpFoundation/ResponseRedirect中找到一些内容),并从那里逐步进行操作.

I'm now going to grep -r "Redirecting to" * the whole framework source code (I expect to find something in Symfony/Components/HttpFoundation/ResponseRedirect) and doing step-by-step from there.

推荐答案

TL; DR

确保POST URL不以斜杠结尾.-但是Laravel 4.1用户首先检查以下更新.

TL;DR

ensure POST URLs do not end with a slash. -- but Laravel 4.1 users check the update below, first.

=======

当它起作用时,这不是迷信-它是 science :-(

When it works, it's not superstition - it's science :-(

一旦我公开了对所有人的宽恕,我就会保证自行寻找 这个答案本来会让我迷惑几个小时的

as soon as I expose my moronity for all to see, I'm guaranteed to find by myself that answer that would otherwise elude me for hours

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

I will argue that Laravel4's HTML message could have been just a bit more informative.

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

The grep found as expected the origin of the redirect:

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加速中:

at that point, a simple backtrace found the origin, very early in Laravel4 spin-up:

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不相同:

As soon as I saw the redirectIfTrailingSlash, I realized that the two URLs sent by the form and by jQuery were not the same:

... action="/search/?uid=1701">   <--- TRAILING SLASH AFTER 'search'

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

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

Why this should happen I don't quite grok, but the solution is fiendishly simple:

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

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

(and ensure .htaccess has no rule to consider the URL a "directory" and add back the slash - but if it had, jQuery would have failed too).

显然,此问题在Laravel 4.1中得到了审查. 升级提到

Apparently, the matter got reviewed in Laravel 4.1. The upgrade mentions

删除重定向尾部斜杠

在bootstrap/start.php文件中,删除对 $ app-> redirectIfTrailingSlash().不再需要此方法,因为 现在,此功能由随附的.htaccess文件处理 框架.

In your bootstrap/start.php file, remove the call to $app->redirectIfTrailingSlash(). This method is no longer needed as this functionality is now handled by the .htaccess file included with the framework.

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

Next, replace your Apache .htaccess file with this new one that handles trailing slashes.

这篇关于Laravel4 POST无法解释的重定向到GET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆