2009-08-20 2 views
18

Я пытаюсь выяснить, как перенаправить на новую страницу (другое приложение, контроллер, действие) и сохранить текущие данные POST.Перенаправление на новую страницу с данными POST (PHP/Zend)

Мое приложение проверяет данные 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, и если это не я хочу, чтобы перенаправить (302) в/app2/например, с того, что те же данные POST. Что-то может быть так?

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

Я могу видеть, как создать новый запрос HTTP с использованием Zend_Http_Client, но я не ищу просто запросить страницу и отображать содержимое. Должен ли я по-прежнему искать Zend_Http_Client? На данный момент я играю с вещами, как это:

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

Я уверен, что я хочу сделать, это возможно с помощью некоторых средств обмана и демона-скакать, но это определенно намекая меня. Любая помощь приветствуется.

- гк

ответ

17

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

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

Я пробовал это и, похоже, заблокировал приложение. Я не вижу никакой активности запроса (используя LiveHTTPHeaders для Firefox), и мой поток httpd просто всплескивает процессор (если смотреть сверху). Я добавлю некоторые записи в код, чтобы увидеть, действительно ли он пойман в бесконечном цикле или нет, потому что мне бы очень хотелось, чтобы это было ответом. – angrychimp

+0

Ну, во-первых, используйте set_time_limit (5) или что-то подобное прямо перед вызовом, так что php будет разбиваться с ошибкой через 5 секунд времени выполнения, вы должны увидеть «цикл» со стеком , Кроме того, не собирается делать другой HTTP-запрос, диспетчер просто изменит параметры контроллера/модуля/действия в Zend_Controller_Request и redispatch. Если по какой-то причине другое действие пересылает или делает что-то странное, что возвращается к исходному действию, вы можете получить цикл. – gnarf

+1

Ну, похоже, это было именно то, что я хотел, за исключением того, что по какой-то причине у нас нет правильно настроенных модулей. У нас есть какая-то дурацкая настройка, в которой каждый доступ к модулю настроен как модуль по умолчанию, и он не знает о других модулях. Идите фигуру. Спасибо, хотя для проверки, gnarf! – angrychimp

0

Поскольку клиент обрабатывает перенаправление после ответа сервера я не думаю, что вы можете сделать много об этом. Например, Firefox запрашивает у пользователя, хочет ли он повторно отправить данные POST в новое местоположение или нет.

Отвратительным решением было бы заполнить и вернуть HTML-форму и автоматически отправить ее с помощью JavaScript. :/

+1

Это предложение действительно заслуживает нисходящего ... – NDM

0

Я не слишком хорошо знаком с Zend специально, но есть два подхода я бы к вашей проблеме:

  1. Хранить данные POST в сессии для жизни этого запроса/redirect
  2. Установите перенаправление как POST и закодируйте данные. Вместо использования перенаправления просто отправьте новый заголовок с POST вместо GET.
13

ИМО вы не можете переадресовать с помощью POST. См. http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3

Как уже говорилось, вы можете сохранить свои POST-данные в сеансе.

+2

Абсолютно верно. Всегда есть способ, как это сделать без него. Это только ваш плохой дизайн приложения: P –

5

Вы можете использовать объект контроллера _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

Можете ли вы добавить некоторые подробности о том, как это будет сделано? –