重定向到新页面并携带POST数据(PHP / Zend)

18
我正在尝试找出如何重定向到一个新页面(不同的应用程序、控制器和操作),并保留当前的POST数据。
我的应用程序正在验证POST数据,如果满足某些条件,我想要重定向到不同的位置,但确保POST数据作为POST数据传递到那个新页面。以下是一个大致的例子:
POST /app1/example HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
    var1=foo&var2=bar

在我的exampleAction(Zend_Controller_Action)中,我检查var1 == foo,如果是,我想用相同的POST数据重定向(302)到/app2/example。像这样做可能行吗?

HTTP/1.x 302 Found
Location: /app2/example
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
    var1=foo&var2=bar

我知道如何使用Zend_Http_Client创建一个新的HTTP请求,但我不只是想请求页面并显示内容。即使是这样,我是否仍应该考虑使用Zend_Http_Client?目前我正在尝试以下内容:

$this->getResponse()->setRedirect('/app2/example/', 302);
$this->getResponse()->setBody(http_build_query($this->_request->getPost()));

我相信通过一些诡计和恶魔舞蹈,我想做的事情肯定是可能的,但它确实让我感到困扰。任何帮助都将不胜感激。

- rk

6个回答

16

为什么不直接将请求从一个控制器转发到另一个控制器,而不是将浏览器重定向到新位置?

return $this->_forward("action", "controller", "module");

1
我试过了,但似乎会锁定应用程序。我没有看到任何请求活动(使用Firefox的LiveHTTPHeaders),我的httpd线程只是将CPU占用率增加了(从top查看)。我将在代码中添加一些日志记录,以查看它是否真的被卡在无限循环中,因为我确实希望这可以成为答案。 - angrychimp
首先,在调用之前使用set_time_limit(5)或类似的东西,这样php将在执行5秒后中断并显示带有堆栈跟踪的错误。此外,它不会发出另一个HTTP请求,Dispatcher只会更改Zend_Controller_Request中的控制器/模块/操作参数并重新分派。如果由于某种原因,其他操作正在转发或执行一些奇怪的调用返回到原始操作,则可能会出现循环。 - gnarf
1
好像这正是我想要的,但由于某些原因,我们的模块配置不正确。我们有一些奇怪的设置,每个访问的模块都被设置为默认模块,并且它不知道其他模块的存在。真是难以理解。无论如何,感谢gnarf的验证! - angrychimp
这并没有回答问题。虽然你帮助了一个人,但在他之后的1000个人来到这里,发现你的答案毫无用处。请回答“问题”——不要告诉他们他们问错了问题。 - B T

13

2
绝对正确。总有一种方法可以在没有它的情况下完成它。这只是你糟糕的应用程序设计 :P - Tomáš Fejfar

7
您可以使用Controller _request对象。
$this->_request->setPost(array(
    'someKey' => 'someValue'
));

那么只需使用 _forward 受保护方法即可。
$this->_forward('yourAction', 'yourController', 'yourModule');

然后,在转发控制器动作中只需调用:
$aPost = $this->_request->getPost();

2
你可以使用重定向操作助手:

http://framework.zend.com/manual/1.12/en/zend.controller.actionhelpers.html#zend.controller.actionhelpers.redirector

这对我很有帮助。它将登录凭据从一个登录界面传递到另一个界面。307 可能会导致浏览器警告用户重定向正在发生,而 303 将重定向并在下一页上填充凭据,但不会提交第二个表单。
$baseUrl = 'https://example.com';
$this->_redirector = $this->_helper->getHelper('Redirector');
$this->_redirector->setCode(307)
   ->setUseAbsoluteUri(true)
   ->gotoUrl($baseUrl . '/home/login',
        array('username' => $authForm->getValue('username'),
              'password' => $authForm->getValue('password')
        )
   );

0
因为客户端在服务器响应之后处理重定向,所以我认为你对此无能为力。例如,Firefox会询问用户是否要重新发送POST数据到新位置。
一个不好的解决方案是使用JavaScript填充并自动提交HTML表单。:/

0

我对Zend不是特别熟悉,但是我会采取两种方法来解决你的问题:

  1. 将POST数据存储在会话中,以便在请求/重定向的生命周期内使用
  2. 将重定向设置为POST,并对数据进行编码。不要使用重定向,而是发送一个新的带有POST而不是GET的头部。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接