更新:我已将其缩小到Ajax通话范围。我可以使用正常的表单提交后,仍然使用相同的PHP代码,它的工作原理。 Ajax没有。所以如果熟悉Ajax的人有一个想法......或者如果你更好地了解如何在没有用户交互的情况下从代码中执行POST ...
更新2: 如果我用下面的代码替换GetPaymentSetup()函数,它也可以使用PostTo。它似乎与重定向有关......
public function GetPaymentSetup() {
$script1 = "<script type=\"text/javascript\">
function post_to_url() {
var form = document.createElement('form');
form.action = '" . self::PROXY_URL . "';
form.method = 'POST';
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'clientId';
input.value = '" . self::CLIENTID . "';
document.body.appendChild(input);
form.appendChild(input);
var input1 = document.createElement('input');
input1.type = 'hidden';
input1.name = 'clientCode';
input1.value = '" . self::CLIENTCODE . "';
document.body.appendChild(input1);
form.appendChild(input1);
var input2 = document.createElement('input');
input2.type = 'hidden';
input2.name = 'postTo';
input2.value = '" . self::POSTTO_URL . "';
document.body.appendChild(input2);
form.appendChild(input2);
var input3 = document.createElement('input');
input3.type = 'hidden';
input3.name = 'target';
input3.value = 'GetPaymentSetup';
document.body.appendChild(input3);
form.appendChild(input3);
form.submit();
}
</script>";
$html2 = "<br><button id='hidformbtn' onclick=\"post_to_url()\">Click 3</button><br>";
echo $script1;
echo $html2;
}
我想这会奏效。在某些情况下我需要自动化它,但这不是问题。我想知道jQuery / Ajax失败的原因。
我到处搜索,但找不到与此系统有关的任何问题。所以我需要一些指导,也许作为未来使用它的人的参考。我的任务是与ModPay.com的支付系统集成。它也被称为TotalTransact。出于测试目的,他们有一个足够简单的页面,您可以执行POST并在没有任何实际数据交换的情况下获取响应。我编写了可以使用此代码的代码,但是当我向&#34; PostTo添加一个选项时,我不会回复一个响应。首先,以下是API文档中如何描述该选项:
如果提供PostTo = URL参数,则调用结果 xxxxx页面会将结果发布到提供的网址而不是 返回包含结果的网页。
我想将结果发布到不同的网址,以便更轻松地拆分解析。如果我不使用此参数,我会从发出请求的页面中获得结果。如果我使用参数,我仍然可以获得成功的POST,但没有回复。他们的开发人员摸不着头脑,所以我更倾向于认为这与我的代码有关。
我已经确认他们可以直接发布到我的PostTo网址。所以我知道这不是问题。我还添加了#34; Access-Control-Allow-Origin&#34;标题,以确保他们可以回发确定,以避免跨域问题。
以下是PHP中的相关代码:
function post($url, $data) {
$header = array("Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
//curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ;
//curl_setopt($curl, CURLOPT_SSLVERSION,3);
//curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
//curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_HEADER, true); //This option returns some data to the screen
curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
//curl_setopt($curl, CURLOPT_COOKIEFILE, ''); //write cookies. empty string to ignore.
//curl_setopt($curl, CURLOPT_COOKIEJAR, ''); //read cookies
//curl_setopt($curl, CURLOPT_VERBOSE, '1');
//curl_setopt($curl, CURLOPT_NOPROXY, 1); // causes POST to fail
//curl_setopt($curl, CURLOPT_HTTPHEADER,array("Expect:"));
//curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
其中
$data = http_build_query($_POST, '', '&');
和$ _POST来自另一个页面上的AJAX调用(代理以避免浏览器CORS问题):
public function GetPaymentSetup($useButton) {
$script = "<script type=\"text/javascript\">";
if($useButton == true) {
$script .= "
$(document).ready(function() {
$(\"button\").click(function() {
";
}
$script .= "
var request = jQuery.ajax ({
type: 'POST',
url: '" . self::PROXY_URL . "',
crossDomain: true,
data: { \"clientId\" : \"" . self::CLIENTID . "\",
\"clientCode\" : \"" . self::CLIENTCODE . "\",
\"postTo\" : \"" . self::POSTTO_URL . "\"
}
success: function(responseData, textStatus, jqXHR) {
$('#dresponse').html(responseData);
},
error: function(responseData, textStatus, errorThrown) {
$('#dresponse').html('Error. POST failed.');
}
});";
if($useButton == true) {
$script .= "
});});";
}
$script .= " </script>";
if($useButton == true)
$html = "<button>click</button><div id='dresponse'></div>";
else
$html = "<div id='dresponse'></div>";
echo $script;
echo $html;
}
任何人都可以解释为什么我使用这一行:
\"postTo\" : \"" . self::POSTTO_URL . "\"
POSTTO_URL页面永远不会得到任何回报。但如果我删除该行,我会得到回复?再次,使用POSTTO_URL,我也不会在原始的AJAX调用中收到错误,因此它可以成为一个成功的POST。我可以通过将CLIENTID更改为其他内容来验证这一点,然后我就会失败。
这是我正在做的事情,还是结果不正确的事情?有没有人有任何与他们融合的经验?
提前致谢!
答案 0 :(得分:0)
没有人对原始Ajax / jQuery失败的原因有任何了解。但我确实有一个可行的解决方案,所以在这里,对于未来寻找TotalTransact / ModPay集成的任何人来说都是如此:
创建一个文件:modPayProcessing.php:
<?php
class modPayProcessing {
const CLIENTCODE = "xxxxxxx";
const CLIENTID = "xxxxxx";
const PROXY_URL = "https://....modPayProxy.php";
const POSTTO_URL = "https://....modPayReceive.php";
public function GetPaymentSetup($useButton=false, $usePostTo=false) {
$script = "<script type=\"text/javascript\">
function post_to_url() {
var form = document.createElement('form');
form.action = '" . self::PROXY_URL . "';
form.method = 'POST';
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'clientId';
input.value = '" . self::CLIENTID . "';
document.body.appendChild(input);
form.appendChild(input);
var input1 = document.createElement('input');
input1.type = 'hidden';
input1.name = 'clientCode';
input1.value = '" . self::CLIENTCODE . "';
document.body.appendChild(input1);
form.appendChild(input1);
";
if($usePostTo === true) {
$script .= "
var input2 = document.createElement('input');
input2.type = 'hidden';
input2.name = 'postTo';
input2.value = '" . self::POSTTO_URL . "';
document.body.appendChild(input2);
form.appendChild(input2);
";
}
$script .= "
var input3 = document.createElement('input');
input3.type = 'hidden';
input3.name = 'target';
input3.value = 'GetPaymentSetup';
document.body.appendChild(input3);
form.appendChild(input3);
form.submit();
}
";
if($useButton == true) {
$html = "<button id='hidformbtn' onclick=\"post_to_url()\">Submit</button>";
$script .= "</script>";
}
else {
$html = "";
$script .= "
if(window.onload) {
var currOnload = window.onload;
var newOnload = function() {
currOnload();
post_to_url();
};
window.lonload = newOnload;
}
else {
window.onload = post_to_url();
}
</script>";
}
echo $script;
echo $html;
}
public function PostPayment($useButton, $usePostTo=false) {
// Same as the above function, but change the input.name/value to be for whatever you want to submit
// Implementations of how to retrieve the data vary, so I am not listing it exactly here, but the basic format is the same.
}
创建一个文件:modPayProxy.php:
//You can use Curl, or you can use php Streams. Below is a function for each:
<?php
function postCurl($url, $data) {
$header = array("Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 3);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HEADER, false); //This option returns some data to the screen
curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
function postStreams($url, $data) {
$params = array(
'http' => array(
'method'=>'POST',
'content'=>$data,
'header'=>array("Content-Type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($data) . "\r\n"),
'user_agent'=>"Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"
)
);
$ctx = stream_context_create($params);
$fp = @fopen($url, 'rb', false, $ctx);
if(!$fp) {
throw new Exception("Problem with $url, $php_errormsg");
}
$response = @stream_get_contents($fp);
fclose($fp);
if($response === false) {
throw new Exception("Problem reading data from $url, $php_errormsg");
}
return $response;
}
if(array_key_exists('target', $_POST)) {
if($_POST['target'] == 'GetPaymentSetup')
$url = GETSETUP_URL;
elseif($_POST['target'] == 'PostPayment')
$url = POST_URL;
else
$url = "";
unset($_POST['target']);
$data = http_build_query($_POST, '', '&');
echo(postStreams($url, $data)); //change to postCurl if you prefer
}
else { // if POSTTO_URL is not used in the calling function.
$postdata = file_get_contents("php://input");
parse_str($postdata, $output);
// Do whatever you want with $output now.
}
创建一个文件modPayReceive.php:
<?php
$postdata = file_get_contents("php://input");
parse_str($postdata, $output);
// Now do whatever you want with $output now.
要发起呼叫,请确保您需要modPayProcessing.php,然后:
$cc = new modPayProcessing();
$cc->GetPaymentSetup(true, false);
如果第二个参数为false,则不会使用POSTTO_URL / modPayReceive.php文件。 第一个参数可以设置为true,以将其作为表单上的按钮。或者假的直接处理(更好的想法,所以你不暴露你的clientID等)