我有一个HTML表单,呈现为
<form method="post" id="mysearch" action="/search/?uid=1701"> <input id="searchterm" type="text" name="query" /> </form>
表单可以通过jQuery $.POST提交,其中url为’/ search’,数据为{uid:’1701′,查询:$(‘#searchterm’).val()}并且可以正常工作.
如果我在输入内容后按ENTER键,从而覆盖jQuery提交,则会发生以下情况:
>按预期方式向服务器发出POST.
> Route :: post(‘/ search’,function(){…不会被调用.
>返回301 a Moved Permanently
> a GET with search parameters lost发布到Redirect指定的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 <!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 question不同,因为预期会有重定向,这是不希望的答案.这是重定向本身,无缘无故地生成(现在).
我怀疑由于某种原因我触发了this other answer中描述的“安全重定向”,这不是由jQuery触发的(因为它将所有内容放在POST中,而在这里我在URL中有一个参数而在POST中有另一个参数,或者因为jQuery使用XHR).
我原以为它可能是一个CSRF防御,但是那个特定的路线没有被屏蔽.作为最后一个资源,我将CSRF保护路由并将令牌添加到表单中,即使它看起来有点像伏都教给我.似乎有些模糊的东西似乎在Rails发生.
我没有一个,而不是两个,而是三个解决方案,巧妙地回避了上述问题的原因:
>(最残酷)阻止表单中的keyUp事件.
>将表单的submit事件重定向到jQuery
>(最透明)将上述事件路由到$(‘#search-button’).click()
…但我想完全没有按钮(我可以用jQuery做)并且完全没有jQuery.同时了解这里发生了什么.我99%肯定我错过了一些明显的东西.
调试
我现在要grep -r“重定向到”*整个框架源代码(我期望在Symfony / Components / HttpFoundation / ResponseRedirect中找到一些东西)并从那里一步一步地进行.
确保POST URL不以斜杠结尾. – 但是Laravel 4.1用户首先检查下面的更新.
=======
它工作时,它不是迷信 – 这是科学:-(
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消息本来可以提供更多信息.
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时,我意识到表单和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中得到了回顾. upgrade提到
Removing Redirect Trailing Slash
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.Next,replace your Apache .htaccess file with this new one that handles trailing slashes.