Перенаправление PHP с параметрами сообщений

У меня есть веб-страница. Эта веб-страница перенаправляет пользователя на другую веб-страницу, более или менее следующим образом:

<form method="post" action="anotherpage.php" id="myform"> <?php foreach($_GET as $key => $value){ echo "<input type='hidden' name='{$key}' value='{$value}' />"; } ?> </form> <script> document.getElementById('myform').submit(); </script> 

Итак, я вижу, что я передаю параметры GET в параметры POST. Не говорите мне, что это плохо, я знаю это сам, и это не совсем то, что я действительно делаю, важно то, что я собираю данные из массива и пытаюсь отправить его на другую страницу через POST. Но если у пользователя отключен JavaScript, это не сработает. Что мне нужно знать: есть ли способ передать POST-параметры с помощью PHP, поэтому перенаправление может быть сделано способом PHP ( header('Location: anotherpage.php'); ) тоже?

Для меня очень важно передать параметры через POST. Я не могу использовать переменную $ _SESSION, потому что веб-страница находится в другом домене, поэтому переменные $ _SESSION отличаются.

Во всяком случае, мне просто нужен способ переноса POST-переменных с помощью PHP ^^

Заранее спасибо!

Нет возможности сделать это непосредственно с сервера, так как данные POST должны быть отправлены браузером.

Но вы можете выбрать альтернативу:

  • Предварительно заполненная форма, автоматически отправленная в ваш пример, может работать, но, как вы написали, это не очень хорошая практика и может оставить пользователей на пустой странице
  • Получите аргументы GET и POST их с завихрением (или любым приличным клиентом http) на второй сайт, а затем передайте результат в браузер. Это называется прокси и может быть хорошим решением imho.
  • Совместное использование сеанса в домене, это невозможно для всех настроек и может быть сложным. После завершения настройки сеансовый обмен почти прозрачен для PHP-кода. Если у вас есть более чем одна потребность в общении между двумя доменами, это может стоить этого.

Пример с curl-решением, код для работы в домене 1:

 //retrieve GET parameters as a string like arg1=0&arg1=56&argn=zz $data = $_SERVER['QUERY_STRING']; // Create a curl handle to domain 2 $ch = curl_init('http://www.domain2.com/target_script.php'); //configure a POST request with some options curl_setopt($ch, CURLOPT_POST, true); //put data to send curl_setopt($ch, CURLOPT_POSTFIELDS, $data); //this option avoid retrieving HTTP response headers in answer curl_setopt($ch, CURLOPT_HEADER, 0); //we want to get result as a string curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //if servers support is and you want result faster, allow compressed response curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); //execute request $result = curl_exec($ch); //show response form domain 2 to client if needed echo $result; 

Вот и все, браузер вашего клиента даже не увидит сервер домена 2, он получит от него только результат. знаете, хотите ли вы перенаправить клиента в домен, сделайте это с помощью классического HTTP-заголовка.

 header('Location: http://www.domain2.com'); 

Конечно, это демо-код с жестко заданными значениями, и вам осталось 2 очка:

  • Безопасность: строка запроса должна быть отфильтрована или воссоздана для передачи только необходимых параметров, и вы должны утверждать, что сервер домена 2 возвратил 200 HTTP-код.
  • Логика приложения не должна нуждаться в небольшой корректировке в этой части: если приложение домена 2 ожидает получения данных в том же запросе, что и посетитель, он этого не сделает. С точки зрения домена 2, клиент, выполняющий запрос POST, будет сервером, на котором размещен домен 1, а не клиентский браузер, важно, чтобы вопросы IP-клиента или другие проверки клиента выполнялись в домене 2. Если запрос POST служит для отображения содержимого для конкретного клиента, также необходимо было выполнить отслеживание на стороне сервера для объединения ранее опубликованных данных с перенаправлением посетителя.

Надеюсь, теперь это станет более ясным и поможет вам

Вы можете переадресовывать запрос POST и включать информацию POST. Однако вам нужно явно вернуть код статуса HTTP 307. Браузеры обрабатывают 302 как перенаправление для GET, игнорируя исходный метод. Это явно указано в документации по HTTP:

Практически это означает, что в PHP вам необходимо установить код состояния до места перенаправления:

  header('HTTP/1.1 307 Temporary Redirect'); header('Location: anotherpage.php'); 

Однако учтите, что в соответствии со спецификацией HTTP пользовательский агент ДОЛЖЕН запрашивать у пользователя, могут ли они повторно отправить информацию POST на новый URL. На практике Chrome не спрашивает, и Safari также не работает, но Firefox будет предоставлять пользователю всплывающее окно, подтверждающее перенаправление. В зависимости от ваших рабочих ограничений, возможно, это нормально, хотя в общем случае это, безусловно, может вызвать путаницу для конечных пользователей.

Это можно сделать с помощью php cUrl lib.

Проверьте это http://www.askapache.com/htaccess/sending-post-form-data-with-php-curl.html.

Спасибо, Sourabh

Возможно. В этой ситуации я бы использовал cURL:

 $url = 'http://domain.com/get-post.php'; foreach($_GET as $key=>$value) { $fields_string .= $key.'='.$value.'&'; } rtrim($fields_string,'&'); //open connection $ch = curl_init(); //set the url, number of POST vars, POST data curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_POST,count($fields)); curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string); //execute post $result = curl_exec($ch); //close connection curl_close($ch); 

Храните данные в сеансе, а затем используйте GET.

Нет. Вы не можете перенаправить заголовок с помощью POST. У вас есть 2 варианта,

  1. Вы можете использовать GET вместо этого, если пункт назначения принимает POST или GET.
  2. В редких случаях мы добавляем кнопку, в которой отключен Javascript.

Вот пример,

 <noscript> <div> <input type="submit" value="Continue"/> </div> </noscript> 

Это покажет кнопку продолжения, если Javascript отключен, поэтому пользователь может нажать, чтобы продолжить.

В качестве примера того, что указывает @Charles, вот рабочая форма покупки PayPal php, которая:

  1. Проверяет ввод с помощью javascript. Если «ОК», он отправляет его, иначе отображается предупреждение.
  2. Проверяет ввод с помощью php. Если ОК, он создает заголовки переадресации и избавляется от HTML тела, иначе он снова отображает ту же форму.

Обратите внимание, что:

  1. Входы должны быть перепроверены на сервере, так как входные данные браузера могут быть подвергнуты неоправданному манипулированию.
  2. Никакой HTML не может выводиться перед командами заголовка, так как они будут игнорироваться с помощью php-предупреждения.
  3. Javascript может проверять входы только на допустимые значения, но без AJAX не сможет проверять сервер на все, что хочет пользователь перед отправкой. Следовательно, этот метод является полным процессом без javascript.
  4. HTML-код не требуется, если цель перенаправления (например, PayPal) обрабатывает только данные POST. Конечно, цели для людей!
  5. К сожалению, 4 означает, что вы не можете отправить только подмножество или даже полный другой набор значений в новый URL-адрес, и чтобы целевая страница обрабатывала данные POST, открытые в браузере пользователя. Вы не можете сделать это, манипулируя массивом $ _POST (это, скорее всего, просто копия фактических данных PHP). Возможно, кто-то знает, как изменить реальный набор данных POST?
  6. Начиная с 5, нет возможности собирать личную информацию об исходной форме и просто отправлять только платежную информацию в форме PayPal или кому бы то ни было через браузер пользователя для их явного подтверждения оплаты. Это означает, что AJAX необходимо сделать, используя две формы: одну, содержащую личную информацию без кнопки, а другую форму с кнопкой покупки PayPal, которая использует AJAX для отправки другой формы и в зависимости от результата представляет свою форму , Вы можете использовать поля, которые PayPal не использует, но они все еще получают информацию, и мы не знаем, что они тратят на данные поданной формы.
  7. Вместо использования AJAX, как в 6, было бы намного проще иметь 3 версии формы:
    1. Первоначальный захват частных данных.
    2. Если проблема, повторите показ формы с предоставленными данными и индикацией неправильных данных или проблем с базой данных.
    3. Если в порядке, форма PayPal, автоматически отправленная javascript в нижней части страницы (form.submit ()) или запрос на отправку вручную кнопкой, если нет javascript.
 <?php // GET POST VARIABLES, ELSE SET DEFAULTS $sAction=(isset($_POST['action'])?$_POST['action']:''); $nAmount=(int)(isset($_POST['action'])?$_POST['amount']:0); // TEST IF AMOUNT OK $bOK=($nAmount>=10); /* TYPICAL CHECKS: 1. Fields have valid values, as a backup to the javascript. 2. Backend can fulfil the request. Such as whether the requested stock item or appointment is still available, and reserve it for 10-15 minutes while the payment goes through. If all OK, you want the new URL page, such as PayPal to open immediately. */ // IF OK if($bOK){ // CHANGE HEADER TO NEW URL $sURL='https://www.paypal.com/cgi-bin/webscr'; header('HTTP/1.1 307 Temporary Redirect'); header('Location: '.$sURL); } ?> <!DOCTYPE html> <html> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <title>Sample post redirection</title> </head> <body> <?php // IF NO ACTION OR NOT OK if(($sAction=='')||!$bOK){ ?> <h1>Sample post redirection</h1> <p>Throw money at me:</p> <form name="pp" action="<?=$_SERVER['REQUEST_URI']?>" method="post" onsubmit="check_form(this)"> <!-- <input type="hidden" name="amount" value="<?=$nAmount?>" /> --> <input type="hidden" name="business" value="paypal.email@yourdomain.com" /> <input type="hidden" name="cmd" value="_xclick" /> <input type="hidden" name="lc" value="AU" /> <input type="hidden" name="item_name" value="Name of service" /> <input type="hidden" name="item_number" value="service_id" /> <input type="hidden" name="currency_code" value="AUD" /> <input type="hidden" name="button_subtype" value="services" /> <input type="hidden" name="no_note" value="0" /> <input type="hidden" name="shipping" value="0.00" /> <input type="hidden" name="on0" value="Private" /> <input type="hidden" name="os0" value="Xxxx xxxxx xxxxx" /> <p>Amount $<input id="amount" type="text" name="amount" value="<?=$nAmount?>" /> $10 or more.</p> <p><button type="submit" name="action" value="buy">Buy</button></p> </form> <p>If all is OK, you will be redirected to the PayPal payment page.<br /> If your browser requires confirmation, click the <cite>OK</cite> button.</p> <script> // JS AT END OF PAGE TO PREVENT HTML RENDER BLOCKING // JS FUNCTION FOR LOCAL CHECKING OF FIELD VALUES function check_form(oForm){ // USE TO DETERMINE IF VALUES CORRECT var oAmount=document.getElementById('amount'); var nAmount=oAmount.value; var bOK=true; var bOK=(nAmount>=10); // EXAMINE VALUES // IF NOT OK if(!bOK){ // INDICATE WHAT'S WRONG, ALERT ETC alert('Stingy @$#&. Pay more!!'); // BLOCK FORM SUBMIT ON ALL BROWSERS event.preventDefault(); event.stopPropagation(); return false; } } </script> <?php } ?> </body> </html> 

В ситуации POST Redirect GET (см. https://en.wikipedia.org/wiki/Post/Redirect/Get ) допустимо использовать переменную сеанса в качестве метода транспортировки данных.

 <?php session_start(); // return is the name of a checkbox in the post-redirect-get.php script. if(isset($_POST['return'])) { // We add some data based on some sort of computation and // return it to the calling script $_SESSION['action']="This string represents data in this example!"; header('location: post-redirect-get.php'); }