Подтвердить что ты не робот

Перенаправление 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 ^^

Спасибо заранее!

4b9b3361

Ответ 1

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

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

  • Предварительно заполненная форма, автоматически отправленная в ваш пример, может работать, но поскольку вы написали ее не очень хорошую практику и можете оставить пользователей на пустой странице
  • Получите аргументы GET и отправьте их с помощью curl (или любого приличного 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 служит для отображения содержимого, специфичного для клиента, вам также необходимо выполнить отслеживание на стороне сервера, чтобы объединить ранее опубликованные данные с перенаправлением посетителя.

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

Ответ 2

Вы можете переадресовывать запрос 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 будет предоставлять пользователю всплывающее окно, подтверждающее перенаправление. В зависимости от ваших рабочих ограничений, возможно, это нормально, хотя в общем случае он, безусловно, может вызвать путаницу для конечных пользователей.

Ответ 4

Это возможно. В этой ситуации я бы использовал 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);

Ответ 5

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

Ответ 6

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

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

Вот пример,

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

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

Ответ 7

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

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

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

  • Входы должны быть перепроверены на сервере, поскольку входы браузера могут быть подвергнуты маневренному манипулированию.
  • HTML-код не может выводиться перед командами заголовка, поскольку они будут игнорироваться с помощью предупреждения php.
  • Javascript может проверять только входные данные для допустимых значений, но без AJAX не сможет проверять сервер на все, что хочет пользователь перед отправкой. Следовательно, этот метод является полным процессом без javascript.
  • Не требуется HTML, если цель перенаправления (например, PayPal) обрабатывает только данные POST. Конечно, цели для людей!
  • К сожалению, 4 означает, что вы не можете отправить только подмножество или даже полный другой набор значений в новый URL-адрес, а также, чтобы целевая страница обрабатывала данные POST в браузере пользователя. Вы не можете сделать это, манипулируя массивом $_POST (это, скорее всего, просто копия фактических данных PHP). Возможно, кто-то знает, как изменить реальный набор данных POST?
  • Начиная с 5, нет возможности собирать личную информацию о оригинальной формы, и просто отправьте только информацию о платежах на формы для PayPal или любого пользователя через браузер пользователя для их явного подтверждения оплаты. Это означает, что AJAX необходимо сделать используя две формы, один из которых содержит личную информацию без кнопки, и другая форма с кнопкой покупки PayPal, которая использует AJAX для отправки другая форма, и в зависимости от результата, представить свою форму. Вы можете использовать поля, которые PayPal не использует, но они все еще получить информацию, и мы не знаем, что они травят представленные данные формы.
  • Вместо использования AJAX, как в 6, было бы намного проще иметь 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="[email protected]" />
   <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 WRONG, ALERT ETC
     alert('Stingy @$#&. Pay more!!');
     
     // BLOCK FORM SUBMIT ON ALL BROWSERS
     event.preventDefault();
     event.stopPropagation();
     return false;
    }
   }
  </script>
<?php
 }
?>
 </body>
</html>

Ответ 8

В ситуации 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 скрипт. 
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');
}