后来才发现,支付宝接口的“alipay_core.function.php”中的getHttpResponse使用了fsockopen+ssl来做远程抓取 ,但是SAE没有开放SSL。不过,支付宝接口的注释也写明:“该函数的功能可以用curl来实现和代替。curl需自行编写。”
支付宝接口的原始getHttpResponse方法如下:
/** * 远程获取数据 * 注意:该函数的功能可以用curl来实现和代替。curl需自行编写。 * $url 指定URL完整路径地址 * @param $input_charset 编码格式。默认值:空值 * @param $time_out 超时时间。默认值:60 * return 远程输出的数据 */ function getHttpResponse($url, $input_charset = '', $time_out = "60") { $urlarr = parse_url($url); $errno = ""; $errstr = ""; $transports = ""; $responseText = ""; if($urlarr["scheme"] == "https") { $transports = "ssl://"; $urlarr["port"] = "443"; } else { $transports = "tcp://"; $urlarr["port"] = "80"; } $fp=@fsockopen($transports . $urlarr['host'],$urlarr['port'],$errno,$errstr,$time_out); if(!$fp) { die("ERROR: $errno - $errstr<br />\n"); } else { if (trim($input_charset) == '') { fputs($fp, "POST ".$urlarr["path"]." HTTP/1.1\r\n"); } else { fputs($fp, "POST ".$urlarr["path"].'?_input_charset='.$input_charset." HTTP/1.1\r\n"); } fputs($fp, "Host: ".$urlarr["host"]."\r\n"); fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); fputs($fp, "Content-length: ".strlen($urlarr["query"])."\r\n"); fputs($fp, "Connection: close\r\n\r\n"); fputs($fp, $urlarr["query"] . "\r\n\r\n"); while(!feof($fp)) { $responseText .= @fgets($fp, 1024); } fclose($fp); $responseText = trim(stristr($responseText,"\r\n\r\n"),"\r\n"); return $responseText; } }
/**
* 远程获取数据
* 注意:该函数的功能可以用curl来实现和代替。curl需自行编写。
* $url 指定URL完整路径地址
* @param $input_charset 编码格式。默认值:空值
* @param $time_out 超时时间。默认值:60
* return 远程输出的数据
*/
function getHttpResponse($url, $input_charset = '', $time_out = "60") {
/* 因SAE 不支持fsockopen + ssl 使用CURL改写 */
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $time_out);
$responseText = curl_exec($ch);
curl_close($ch);
return $responseText;
}
这样就可以完美解决“ERROR: 501 - protocol error”的问题了。使用支付宝接口提供的Demo,测试了一个确认发货,果然成功了。
最后,感谢SAE的文峰的热心帮忙。