纠缠多日的post请求没有正确返回值的问题终于解决
2014-10-31 10:37
681 查看
这几天合作商家给了一个订单接口以供调用,于是我就使用php惯用的curl方式调用:
可是调用时总是没有返回正常的值,总是返回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头的部分:
于是,奇迹发生了!结果果然正常了~~~ ^_<!
我猜测,也许curl默认是对发送的内容进行了urlencode加密所以导致对方商家服务器端不能接收到正常的请求~~
其实php可以使用CURLOPT_HTTPHEADER来设置所有你想设置的头,甚至是这样伪造一个header头:
以后当使用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)。
$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)。
相关文章推荐
- 解决axios发送post请求返回400状态码的问题
- 很多天都没有解决的问题,今天终于搞定了!
- ASP.NET Post页面及验证视图状态MAC失败问题正确的解决办法
- windows 2008初体验常见问题: 无线网络"没有正确配置为使用IP协议" 错误解决办法
- 解决io_service::run在没有任务就返回的问题
- 解决“请求的名称有效并且在数据库中找到,但是它没有相关的正确的数据来被解析”
- 解决 IIS "服务没有及时响应启动或控制请求" 问题
- 熬了个通宵,终于把在ASP里调用存储过程不返回结果集的问题解决了。
- 解决ASP.NET MVC的FileStreamResult无法正确返回数据问题
- ASP.NET Post页面及验证视图状态MAC失败问题的正确解决办法
- 用HttpWebRequest做POST请求时返回Http 417 错误解决方法
- ASP.NET Post页面及验证视图状态MAC失败问题正确的解决办法
- 让人郁闷了好久的问题,终于解决了,之前网上也看到一些解决方法,但大多没有解决问题,所以记录下来,以供参考之用(ADO Could Not Find The Specified Provider)
- 在使用Hibernate时,因为一个查询需要更多的表连接而要使用SQL来解决性能问题。然而返回的结果集中包含了没有映射的Entity类中的表字段,在这个SQL中还有使用如何将层次关系的父子结点显示为横行
- 解决“找不到请求的 .Net Framework 数据提供程序。可能没有安装”的问题
- windows 2008初体验常见问题: 无线网络"没有正确配置为使用IP协议" 错误解决办法
- 解决HttpContext.Current.Request.Files返回的文件个数不正确问题
- 解决一个我之前没有解决的问题[后台编码ajax请求的内容,前台js解码]
- oracle10g "数据源管理器"找不到应用程序,可能是程序没有正确安装"问题解决
- jQuery.get、jQuery.getJSON、jQuery.post无法返回JSON问题的解决方法