Перенаправление PHP с данными POST

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

Моя ситуация:

Страница A: [checkout.php] Клиент заполняет свои платежные реквизиты.

Страница B: [process.php] Создайте номер счета и сохраните сведения о клиенте в базе данных.

Страница C: [thirdparty.com] Третий платежный шлюз (ТОЛЬКО ПРИНИМАЕТ ПОЧТОВЫЕ ДАННЫЕ).

Клиент заполняет свои данные и настраивает свою тележку на странице А, затем отправляет на страницу В. Внутри process.php хранятся POSTED-данные внутри базы данных и генерируются номер счета-фактуры. После этого отправьте данные клиента и номер счета-фактуры на платежный шлюз третьей стороны. Проблема заключается в выполнении POST на стр. B. cURL может отправлять данные на страницу C, но проблема заключается в том, что страница не перенаправляется на страницу C. Клиент должен заполнить данные кредитной карты на странице C.

Третий платежный шлюз дал нам образец API, образец - POST номер счета-фактуры вместе с детальностью клиента. Мы не хотим, чтобы система генерировала избыток нежелательных номеров счетов.

Есть ли какое-либо решение для этого? Наше текущее решение заключается в том, чтобы клиент мог заполнить детали на странице А, а затем на странице В мы создаем другую страницу, на которой показаны все данные о клиентах, где пользователь может нажать кнопку CONFIRM на POST на страницу C.

Наша цель - клиенту только один раз щелкнуть.

Надеюсь, мой вопрос ясен:)

Ответ 1

Создайте форму на странице B со всеми необходимыми данными и действием, установленными на странице C, и отправьте их с помощью JavaScript при загрузке страницы. Ваши данные будут отправлены на страницу C без особых хлопот для пользователя.

Это единственный способ сделать это. Переадресация - это HTTP-заголовок 303, который вы можете прочитать на http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html, но я приведу некоторые из них:

Ответ на запрос может быть найденный под другим URI и СЛЕДУЕТ извлекаться с использованием метода GET на этот ресурс. Этот метод существует прежде всего, чтобы обеспечить выход POST-активирован script для перенаправления пользовательский агент к выбранному ресурсу. новый URI не является заменой ссылки для первоначально запрошенного ресурса. Ответ 303 НЕ ДОЛЖЕН быть кэширован, но ответ на второй (перенаправленный) запрос может быть кэшируется.

Единственный способ добиться того, что вы делаете, - это промежуточная страница, которая отправляет пользователя на страницу C. Здесь небольшой/простой фрагмент того, как вы можете это сделать:

<form id="myForm" action="Page_C.php" method="post">
<?php
    foreach ($_POST as $a => $b) {
        echo '<input type="hidden" name="'.htmlentities($a).'" value="'.htmlentities($b).'">';
    }
?>
</form>
<script type="text/javascript">
    document.getElementById('myForm').submit();
</script>

У вас также должна быть простая форма подтверждения в теге noscript, чтобы пользователи, не имеющие Javascript, могли использовать вашу службу.

Ответ 2

/**
 * Redirect with POST data.
 *
 * @param string $url URL.
 * @param array $post_data POST data. Example: array('foo' => 'var', 'id' => 123)
 * @param array $headers Optional. Extra headers to send.
 */
public function redirect_post($url, array $data, array $headers = null) {
    $params = array(
        'http' => array(
            'method' => 'POST',
            'content' => http_build_query($data)
        )
    );
    if (!is_null($headers)) {
        $params['http']['header'] = '';
        foreach ($headers as $k => $v) {
            $params['http']['header'] .= "$k: $v\n";
        }
    }
    $ctx = stream_context_create($params);
    $fp = @fopen($url, 'rb', false, $ctx);
    if ($fp) {
        echo @stream_get_contents($fp);
        die();
    } else {
        // Error
        throw new Exception("Error loading '$url', $php_errormsg");
    }
}

Ответ 3

У меня есть другое решение, которое делает это возможным. Это требует, чтобы клиент запускал Javascript (который, на мой взгляд, является справедливым требованием в наши дни).

Просто используйте запрос AJAX на странице A, чтобы перейти и сгенерировать номер вашего счета и информацию о клиенте в фоновом режиме (предыдущая страница B), а затем, как только запрос будет успешно возвращен с правильной информацией, просто заполните форму отправки на ваш платежный шлюз (Страница C).

Это приведет к достижению результата пользователя только нажатием одной кнопки и перехода к платежному шлюзу. Ниже приведен псевдокод

HTML:

<form id="paymentForm" method="post" action="https://example.com">
  <input type="hidden" id="customInvoiceId" .... />
  <input type="hidden" .... />

  <input type="submit" id="submitButton" />
</form>

JS (используя jQuery для удобства, но тривиально, чтобы сделать чистый Javascript):

$('#submitButton').click(function(e) {
  e.preventDefault(); //This will prevent form from submitting

  //Do some stuff like build a list of things being purchased and customer details

  $.getJSON('setupOrder.php', {listOfProducts: products, customerDetails: details }, function(data) {
  if (!data.error) {
    $('#paymentForm #customInvoiceID').val(data.id);
    $('#paymentForm').submit();   //Send client to the payment processor
  }
});

Ответ 4

$ _SESSION - ваш друг, если вы не хотите связываться с Javascript

Допустим, вы пытаетесь передать электронное письмо:

На странице A:

// Start the session
session_start();

// Set session variables
$_SESSION["email"] = "[email protected]";

header('Location: page_b.php');

И на странице B:

// Start the session
session_start();

// Show me the session!  
echo "<pre>";
print_r($_SESSION);
echo "</pre>";

Чтобы уничтожить сеанс

unset($_SESSION['email']);
session_destroy();

Ответ 5

Вы можете позволить PHP делать POST, но тогда ваш php получит ответ со всеми возможными осложнениями. Я думаю, что самым простым было бы позволить пользователю выполнить POST.

Итак, как бы вы ни предложили, вы получите эту часть:

Детали заполнения клиента на странице A, а затем на странице B мы создаем другую страницу, показываем все детали клиента там, нажмите кнопку CONFIRM, а затем POST на страницу C.

Но вы действительно можете сделать javascript submit на странице B, поэтому нет необходимости в клике. Сделайте его "перенаправляющей" страницей с анимацией загрузки, и вы установите.

Ответ 6

Я знаю, что это старый вопрос, но у меня есть еще одно альтернативное решение с jQuery:

var actionForm = $('<form>', {'action': 'nextpage.php', 'method': 'post'}).append($('<input>', {'name': 'action', 'value': 'delete', 'type': 'hidden'}), $('<input>', {'name': 'id', 'value': 'some_id', 'type': 'hidden'}));
actionForm.submit();

В приведенном выше коде используется jQuery для создания тега формы, добавления скрытых полей в качестве полей для отправки и отправки его последним. Страница перейдет на целевую страницу формы с прикрепленными данными POST.

p.s. Для этого случая требуются JavaScript и jQuery. Как было предложено в комментариях к другим ответам, вы можете использовать тег <noscript> для создания стандартной HTML-формы в случае, если JS отключен.

Ответ 7

Существует простой взлом, используйте $_SESSION и создайте array опубликованных значений, и как только вы перейдете к File_C.php, вы можете использовать его, после чего вы обрабатываете его после этого.

Ответ 8

Вы можете использовать сеансы для сохранения данных $_POST, затем извлечь эти данные и установить для них значение $_POST для последующего запроса.

Пользователь отправляет запрос на /dirty-submission-url.php
Делать:

if (session_status()!==PHP_SESSION_ACTIVE)session_start();
     $_SESSION['POST'] = $_POST;
}
header("Location: /clean-url");
exit;

Затем браузер перенаправляет на ваш сервер и запрашивает /clean-submission-url. У вас будет внутренняя маршрутизация, чтобы понять, что с этим делать.
В начале запроса вы сделаете:

if (session_status()!==PHP_SESSION_ACTIVE)session_start();
if (isset($_SESSION['POST'])){
    $_POST = $_SESSION['POST'];
    unset($_SESSION['POST']);
}

Теперь через оставшуюся часть вашего запроса вы можете получить доступ к $_POST как и при первом запросе.

Ответ 9

Я знаю, что вопрос ориентирован на php, но лучший способ перенаправить запрос POST, вероятно, использовать .htaccess, то есть:

RewriteEngine on
RewriteCond %{REQUEST_URI} string_to_match_in_url
RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^(.*)$ https://domain.tld/$1 [L,R=307]

Объяснение:

По умолчанию, если вы хотите перенаправить запрос с данными POST, браузер перенаправляет его через GET с помощью 302 redirect. При этом также удаляются все данные POST, связанные с запросом. Браузер делает это в качестве меры предосторожности для предотвращения непреднамеренной повторной отправки транзакции POST.

Но что, если вы все равно хотите перенаправить POST-запрос со своими данными? В HTTP 1.1 для этого есть код состояния. Код состояния 307 указывает, что запрос должен быть повторен с тем же методом HTTP и данными. Таким образом, ваш запрос POST будет повторяться вместе с его данными, если вы используете этот код состояния.

SRC

Ответ 10

Попробуй это:

Отправьте данные и запрос с заголовком http на странице B для перенаправления на шлюз

<?php
$host = "www.example.com";
$path = "/path/to/script.php";
$data = "data1=value1&data2=value2";
$data = urlencode($data);

header("POST $path HTTP/1.1\\r\
" );
header("Host: $host\\r\
" );
header("Content-type: application/x-www-form-urlencoded\\r\
" );
header("Content-length: " . strlen($data) . "\\r\
" );
header("Connection: close\\r\
\\r\
" );
header($data);
?>

Дополнительные заголовки:

Accept: \*/\*
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like 
Gecko) Chrome/74.0.3729.169 Safari/537.36

Ответ 11

function post(path, params, method) {
    method = method || "post"; // Set method to post by default if not specified.



    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
         }
    }

    document.body.appendChild(form);
    form.submit();
}

Пример:

 post('url', {name: 'Johnny Bravo'});