您的位置:首页 > 其它

纠缠多日的post请求没有正确返回值的问题终于解决

2014-10-31 10:37 681 查看
这几天合作商家给了一个订单接口以供调用,于是我就使用php惯用的curl方式调用:

$url = 'http://www.someapi.com/api';

$body = '<?xml version="1.0" encoding="utf-8"?>
<returndata>
<somexml></somexml>
</returndata>';

$result = api_notice_increment($url,$body);

echo '<pre>';print_r($result);exit;

function api_notice_increment($url, $data)
{

$ch = curl_init();

curl_setopt($ch, CURLOPT_HEADER,0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$lst['rst'] = curl_exec($ch);
$lst['info'] = curl_getinfo($ch);
curl_close($ch);
return $lst;
}


可是调用时总是没有返回正常的值,总是返回500,于是我从网上寻找可以模拟http请求的工具,找到了这个:http://segmentfault.com/q/1010000000491112

可是我使用这个在线工具的时候:
http://tool.sufeinet.com/httphelper.aspx?url=http://www.cnblogs.com/hongfei/p/3705089.html&type=url
却可以正常返回,后来我发现,我选择ContentType为text/html时就可以正常返回,而在选择为application/x-www-form-urlencoded时便发生跟我一样的相同错误,返回:

返回的HTML:

远程服务器返回错误: (500) 内部服务器错误。

所以我猜测也许问题就发生在设置的头部ContentType,于是我修改了我的代码,加入了设置header头的部分:

$url = 'http://www.someapi.com/api';

$body = '<?xml version="1.0" encoding="utf-8"?>
<returndata>
<somexml></somexml>
</returndata>';

$result = api_notice_increment($url,$body);

echo '<pre>';print_r($result);exit;

function api_notice_increment($url, $data)
{

$ch = curl_init();

<span style="background-color: rgb(255, 255, 0);">curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/html", "Content-length: ".strlen($data))); </span>

curl_setopt($ch, CURLOPT_HEADER,0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);

curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$lst['rst'] = curl_exec($ch);
$lst['info'] = curl_getinfo($ch);
curl_close($ch);
return $lst;
}


于是,奇迹发生了!结果果然正常了~~~ ^_<!

我猜测,也许curl默认是对发送的内容进行了urlencode加密所以导致对方商家服务器端不能接收到正常的请求~~

其实php可以使用CURLOPT_HTTPHEADER来设置所有你想设置的头,甚至是这样伪造一个header头:

$headers = array();
$headers[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
$headers[] = 'Connection: Keep-Alive';
$headers[] = 'Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3';
$headers[] = 'Accept-Encoding: gzip, deflate';
$headers[] = 'Host: 4pda.ru';
$headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20100101 Firefox/22.0';

$ch = curl_init();

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);


以后当使用curl时发生了什么错误的时候,记得看看是不是header中需要调整~~~

至于具体application/x-www-form-urlencoded的意义:

application/x-www-form-urlencoded: 窗体数据被编码为名称/值对。这是标准的编码格式。 multipart/form-data:
窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分。 text/plain: 窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。
 补充
form的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x-www-form-urlencoded。 当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2...),然后把这个字串append到url后面,用?分割,加载这个新的url。
当action为post时候,浏览器把form数据封装到http body中,然后发送到server。 如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。 但是如果有type=file的话,就要用到multipart/form-data了。浏览器会把整个表单以控件为单位分割,并为每个部分加上Content-Disposition(form-data或者file),Content-Type(默认为text/plain),name(控件name)等信息,并加上分割符(boundary)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐