PHP ::模拟,将用户转发到页面
我正在开发一个链接到Protx VSP Direct付款网关的PHP应用程序。为了处理信用卡处理公司的" 3D安全"请求,我需要将用户转发到另一个网站,模仿已发布的表单。我正在尝试使用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的内容,并且不会将用户转发到任何地方。我已经尝试了Googling,并尽可能多地阅读,但无法弄清我所缺少的内容。有任何想法吗?如果可以避免的话,我不想创建自动提交自身的HTML表单。
谢谢你的帮助 :-)
解决方案
3D安全API不允许我们在后台执行请求。我们需要将用户转发到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>
我想你对卷曲的作用有点困惑。它完全按照解释进行操作,其行为类似于浏览器,并调用该网站并返回该帖子的内容。我不知道我们实际上可以如何重定向浏览器服务器端并代表帖子。实际上,我将创建一个Javascript解决方案来执行此操作。
要将用户重定向到PHP中的另一个页面,我们可以发送一个标题(" Location:http://example.com/newpage");`。但是,不幸的是,由于程序重定向,所有POST变量都将被删除(出于安全原因)。如果要使用户的浏览器将POST请求发送到其他URL,则必须创建一个提交自身的表单。 :(
我宁愿在幕后使用诸如cURL之类的东西,因为我不能保证我的用户将启用JS,并且显示表单会导致我宁愿避免其他一些问题。这是我的计划B ;-)
我们可以使用fsockopen()重定向到新网站,同时保留POST变量。这里有一个很好的教程,说明如何完成此操作。
万一该网站被Internet怪兽吞噬,我已经复制并粘贴了该功能,但我建议查看原始网站的上下文。
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的功能,我想我会选择使用JS自动提交的HTML表单。为我创造了更多的工作,但是如果这是唯一的方法,那我就必须这样做。
谢谢大家的帮助。
我认为在这种情况下,我们需要使用表格。卡付款公司的网站需要由用户的浏览器访问,而不是服务器端代码。
是的,与3dsecure等进行集成非常烦人,但是按预期使用它们确实提供了真正的安全性提升。
也许我缺少了一些东西;看来我们正在尝试接收用户的数据,通过cURL将其转发到付款处理器,然后将用户重定向到某个地方。正确的?
如果是这样,我们只需将其放在代码末尾即可:
header(" Location:http://www.yoursite.com/yoururl");
但是,为了使其正常工作,脚本在处理过程中无法将任何内容发送到客户端。这意味着该脚本不应在模板的中间执行,另一个难题是在文件开头的空白处,在开始标记之前。
如果我们需要保存原始POST事务中的数据,请使用会话进行保存。
这应该适用于无JS解决方案。
我可能完全错了,但听起来我们正在尝试执行类似于代理模式的操作。
我为与我合作过的其他网站实施了类似的模式,并且确实需要进行一些修补才能正确。
我将RETURN_TRANSFER设置为TRUE,以便我们可以分析检索到的响应并根据该响应执行应用程序级操作。
http://en.wikipedia.org/wiki/Proxy_pattern
祝你好运。
我发现上面的sendToHost()函数非常有用,但是源代码中有一个错字,需要花费一些时间进行调试:Content-type标头值的" form-"和" urlencoded"之间应为" application / x -www-form-urlencoded'