PHPredirectPOST数据
我在这方面做了一些研究,有些专家说这是不可能的 ,所以我想请求一个替代scheme。
我的情况:
页面A:[checkout.php]客户填写他们的账单细节。
页面B:[process.php]生成发票号码并将客户详细信息存储在数据库中。
页面C:[thirdparty.com]第三支付网关(仅接受邮政数据)。
客户填写他们的详细信息,在页面A中设置他们的购物车,然后发送到页面B.在process.php中,将发布的数据存储在数据库中并生成发票号码。 之后,将客户数据和发票号码发布到thirdparty.com支付网关。 问题是在页面B中进行POST。cURL能够将数据发布到页面C,但问题是页面没有redirect到页面C.客户需要在页面C上填写信用卡详细信息。
第三方支付网关确实给我们提供了API样本,样本与客户详细信息一起POST发票号码。 我们不希望系统产生多余的不需要的发票号码。
有没有解决scheme? 我们目前的解决scheme是让客户在页面A中填写详细信息,然后在页面B中创build另一个页面,其中显示所有客户详细信息,用户可以点击确认button发布到页面C.
我们的目标是客户只需点击一次。
希望我的问题是明确的:)
在页面B上生成一个表单,并将所有必需的数据和操作设置为页面C,并在页面加载时使用JavaScript进行提交。 您的数据将被发送到页面C,而不会给用户带来任何麻烦。
这是做到这一点的唯一方法。 redirect是一个303 HTTP头,你可以在http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html上阅读,但是我会引用其中的一些:;
对请求的响应可以在不同的URI下find,并且应该在该资源上使用GET方法进行检索。 此方法主要用于允许POST激活的脚本的输出将用户代理redirect到选定的资源。 新的URI不是最初请求的资源的替代参考。 303响应绝不能被caching,但对第二个(redirect的)请求的响应可能是可caching的。
实现你正在做的唯一的方法是用一个中间页面,将用户发送到页面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的用户能够使用你的服务。
/** * 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"); } }
我有另一个解决scheme,使这成为可能。 它要求客户端运行Javascript(我认为这是一个公平的要求)。
只需在页面A上使用AJAX请求,并在后台(您的上一页B)中生成发票号码和客户详细信息,然后一旦请求成功返回并显示正确的信息 – 只需填写表单提交到您的支付网关(页面C)。
这将实现您的结果,用户只需点击一个button并进入支付网关。 下面是一些伪代码
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 } });
你可以让PHP做一个POST,但是你的PHP会得到回报,带来各种各样的麻烦。 我认为最简单的就是让用户去做POST。
所以,你所build议的,你会得到这个部分:
客户在页面A中填写详细信息,然后在页面B中创build另一个页面,其中显示所有客户详细信息,点击确认button,然后发布到页面C.
但是实际上你可以在页面B做一个javascript提交,所以不需要点击。 使用加载animation将其设为“redirect”页面,然后进行设置。
有一个简单的黑客攻击,使用$_SESSION
并创build一个张贴值的array
,一旦你去的File_C.php
你可以使用它,然后你处理之后,摧毁它。
我知道这是一个老问题,但我有另一种解决scheme与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创build一个表单标签,将隐藏的字段附加为post字段,并最后提交。 该页面将转发到附带POST数据的表单目标页面。
ps JavaScript和jQuery对于这种情况是必需的。 正如其他答案的评论所build议的那样,在JS被禁用的情况下,可以使用<noscript>
标签创build一个标准的HTML表单。
$ _SESSION是你的朋友,如果你不想混淆Javascript,并确定它有点不安全。
假设您正在尝试传送电子邮件:
在页面A:
// Start the session session_start(); // Set session variables $_SESSION["email"] = "awesome@email.com"; header('Location: page_b.php');
并在页面B:
// Start the session session_start(); // Show me the session! echo "<pre>"; print_r($_SESSION); echo "</pre>";
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'});