PHP :: Emulate <form method = "post">, перенаправляя пользователя на страницу

Я работаю над приложением PHP, которое подключается к Protx VSP Direct payment gateway. Для обработки запросов «3D Secure» от компании, занимающейся обработкой кредитных карт, мне нужно перенаправить пользователя на другой веб-сайт, имитируя опубликованную форму. Я пытаюсь использовать библиотеки cURL, но, похоже, столкнулся с проблемой. Мой код следующий:

<?php  
$ch = curl_init();  
// Set the URL  
curl_setopt($ch, CURLOPT_URL, 'http://www.google.com/');  
// Perform a POST  
curl_setopt($ch, CURLOPT_POST, 1);  
// If not set, curl prints output to the browser  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 0);   
// Set the "form fields"  
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);  
$output = curl_exec($ch);  
curl_close($ch);  
?>  

Все, что это делает, - это захват содержимого переданного URL-адреса и никуда не перенаправляет пользователя. Я пробовал гуглить и читать столько, сколько могу, но не могу понять, что мне не хватает. Есть идеи? Я не хочу создавать HTML-форму, которая автоматически отправляется, если я могу этого избежать.

Спасибо за любую помощь :-)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
5
0
6 782
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Ответ принят как подходящий

API 3D Secure не позволяет выполнять запрос в фоновом режиме. Вам необходимо перенаправить пользователя на сайт с 3D-безопасностью. Используйте javascript для автоматической отправки формы. Вот что предлагает наш провайдер:

<html> 
    <head> 
        <title>Processing your request...</title> 
    </head> 
    <body OnLoad = "OnLoadEvent();"> 
        <form name = "downloadForm" action = "<%=RedirURL%>" method = "POST"> 
            <noscript> 
                <br> 
                <br> 
                <div align = "center"> 
                    <h1>Processing your 3-D Secure Transaction</h1> 
                    <h2>JavaScript is currently disabled or is not supported by your browser.</h2><BR> 
                    <h3>Please click Submit to continue the processing of your 3-D Secure transaction.</h3><BR> 
                    <input type = "submit" value = "Submit"> 
                </div> 
            </noscript> 
            <input type = "hidden" name = "PaReq" value = "<%=PAREQ%>"> 
            <input type = "hidden" name = "MD" value = "<%=TransactionID%>"> 
            <input type = "hidden" name = "TermUrl" value = "<%=TermUrl%>"> 
        </form> 
        <SCRIPT LANGUAGE = "Javascript"> 
            <!-- 
            function OnLoadEvent() { 
                document.downloadForm.submit(); 
            } 
            //--> 
        </SCRIPT> 
    </body> 
</html>

Я думаю, вы немного не понимаете, что делает curl. Он делает именно то, что вы объяснили, он действует как браузер, обращается к сайту и возвращает содержимое этого сообщения. Я не знаю, как вы можете перенаправить серверную часть браузера и представить сообщение. Я бы на самом деле создал решение Javascript для этого.

Чтобы перенаправить пользователя на другую страницу в PHP, вы можете отправить header("Location: http://example.com/newpage");. Однако, к сожалению, перенаправление вашей программы приводит к удалению всех переменных POST (по соображениям безопасности). Если вы хотите, чтобы браузер пользователя отправлял запрос POST на другой URL-адрес, вам нужно будет создать форму, которая отправляет сама себя. :(

Я бы предпочел использовать что-то за кулисами, например cURL, поскольку я не могу гарантировать, что у моих пользователей будет включен JS, а отображение формы вызывает некоторые другие проблемы, которых я бы предпочел избежать. Но это мой план Б ;-)

Вы не можете сделать 3D-безопасность «за кулисами», так как пользователя нужно перенаправить. Решение, которое я описал выше, - лучший способ сделать это, по крайней мере, так думает наш поставщик платежей.

neu242 19.09.2008 23:46

Вы можете использовать fsockopen () для перенаправления на новый веб-сайт с сохранением ваших переменных POST. Есть хорошее руководство о том, как добиться этого здесь.

В случае, если этот веб-сайт будет съеден интернет-монстром, я скопировал и вставил функцию, но я предлагаю проверить исходный веб-сайт для контекста.

function sendToHost($host,$method,$path,$data,$useragent=0)
{
    // Supply a default method of GET if the one passed was empty
    if (empty($method)) {
        $method = 'GET';
    }
    $method = strtoupper($method);
    $fp = fsockopen($host, 80);
    if ($method == 'GET') {
        $path .= '?' . $data;
    }
    fputs($fp, "$method $path HTTP/1.1\r\n");
    fputs($fp, "Host: $host\r\n");
    fputs($fp,"Content-type: application/x-www-form- urlencoded\r\n");
    fputs($fp, "Content-length: " . strlen($data) . "\r\n");
    if ($useragent) {
        fputs($fp, "User-Agent: MSIE\r\n");
    }
    fputs($fp, "Connection: close\r\n\r\n");
    if ($method == 'POST') {
        fputs($fp, $data);
    }

    while (!feof($fp)) {
        $buf .= fgets($fp,128);
    }
    fclose($fp);
    return $buf;
}

Ах, если я неправильно понял, что делает cURL, думаю, я соглашусь на HTML-форму с автоматической отправкой JS. Это создает для меня немного больше работы, но если это единственный способ, мне придется это сделать.

Всем спасибо за помощь.

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

Да, 3dsecure и т. д. Довольно неприятны для интеграции, но они действительно обеспечивают повышение безопасности - используйте его по назначению.

Может я что-то упускаю; похоже, вы пытаетесь получить данные пользователя, переслать их через cURL обработчику платежей, а затем куда-то перенаправить пользователя. Правильно?

Если это так, все, что вам нужно сделать, это просто поместить это в конец вашего кода:

заголовок («Местоположение: http://www.yoursite.com/yoururl»);

Однако, чтобы это работало, сценарий НЕ МОЖЕТ отправлять что-либо клиенту во время обработки; это означает, что скрипт не должен выполняться в середине шаблона, а другая ошибка - это пробел в начале файла перед открывающим тегом.

Если вам нужно сохранить данные из исходной транзакции POST, используйте сеанс для их сохранения.

Это должно работать для решения без JS.

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

fistameeny 20.09.2008 02:10

Возможно, я совершенно ошибаюсь, но похоже, что вы пытаетесь сделать что-то похожее на шаблон прокси.

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

Я бы установил для RETURN_TRANSFER значение TRUE, чтобы вы могли анализировать полученный ответ и выполнять действия на уровне приложения в зависимости от него.

http://en.wikipedia.org/wiki/Proxy_pattern

Удачи.

Я нашел вышеупомянутую функцию sendToHost () очень полезной, но в источнике есть опечатка, отладка которой заняла некоторое время: значение заголовка Content-type содержит пробел между 'form-' и 'urlencoded' - должно быть 'application / x-www-form-urlencoded '

Другие вопросы по теме