通过CURL将XML文件发送到WebServices时出错


Error Sending XML file by CURL to WebServices

我正试图通过POST方法通过CURL向经过身份验证的Web服务发送一个XML,但由于某种原因,服务器拒绝了该XML文件,我给了我一个错误500,但是另一个Web服务(而不是通过GET方法)没有问题。下面的代码是我正在尝试的。

  <?php
  $request_xml = "<?xml version='"1.0'" encoding='"utf-8'" ?> 
  <FiltroLicitaciones xmlns:xsd='"http://www.w3.org/2001/XMLSchema'"xmlns:xsi='"http://www.w3.org/2001/XMLSchema-instance'"> 
  <CantidadRegistro>10</CantidadRegistro> 
  <Texto>memo</Texto> 
  <CodigoRegion xsi:nil='"true'" /> 
  <CodigoEstado>1</CodigoEstado> 
  <TipoFecha>FechaPublicacion</TipoFecha> 
  <FechaDesde>2011-06-01T00:00:00</FechaDesde> 
  <FechaHasta>2011-08-01T00:00:00</FechaHasta> 
  </FiltroLicitaciones>";
  //Initialize handle and set options 
  $username = 'user'; 
  $password = 'pass'; 
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'https://www.mercadopublico.cl/movil/licitaciones/porFecha');  
 //curl_setopt($ch, CURLOPT_URL, "http://localhost/server.php"); 
   curl_setopt($ch, CURLOPT_USERPWD, $username.':'.$password); 
   curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); 
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
   curl_setopt($ch, CURLOPT_HEADER, 1); 
   curl_setopt($ch, CURLOPT_TIMEOUT, 4); 
   curl_setopt($ch, CURLOPT_POSTFIELDS, $request_xml);
   $result = curl_exec($ch); 
   curl_close($ch); 
   print_r($result); 
   ?>

我不知道是否会出现XML格式错误,但服务器返回了一个随机的500错误,标题如下:

HTTP/1.1 500 The server encountered an error processing the request. Please see the      server logs for more details.
Cache-Control: private
Content-Length: 1047
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 30 Jul 2012 23:53:05 GMT

我在本地服务器上做了一个测试,看看数据来了,下面的结果是:

HTTP/1.1 200 OK 
Date: Mon, 30 Jul 2012 23:41:50 GMT 
Server: Apache/2.2.22 (Fedora) 
X-Powered-By: PHP/5.3.14 
Content-Length: 2450 
Connection: close 
Content-Type: text/html; charset=UTF-8 
Array 
( 
 [GLOBALS] => Array 
 *RECURSION* 
  [_POST] => Array 
    ( 
        [<?xml version] => "1.0" encoding="utf-8" ?> 
        <FiltroLicitaciones xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
        <CantidadRegistro>10</CantidadRegistro> 
        <Texto>memo</Texto> 
        <CodigoRegion xsi:nil="true" /> 
        <CodigoEstado>1</CodigoEstado> 
        <TipoFecha>FechaPublicacion</TipoFecha> 
        <FechaDesde>2011-06-01T00:00:00</FechaDesde> 
        <FechaHasta>2011-08-01T00:00:00</FechaHasta> 
        </FiltroLicitaciones> 
    ) 
[_GET] => Array 
    ( 
    ) 
[_COOKIE] => Array 
    ( 
    ) 
[_FILES] => Array 
    ( 
    ) 
[_ENV] => Array 
    ( 
    ) 
[_REQUEST] => Array 
    ( 
        [<?xml version] => "1.0" encoding="utf-8" ?> 
        <FiltroLicitaciones xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
        <CantidadRegistro>10</CantidadRegistro> 
        <Texto>memo</Texto> 
        <CodigoRegion xsi:nil="true" /> 
        <CodigoEstado>1</CodigoEstado> 
        <TipoFecha>FechaPublicacion</TipoFecha> 
        <FechaDesde>2011-06-01T00:00:00</FechaDesde> 
        <FechaHasta>2011-08-01T00:00:00</FechaHasta> 
        </FiltroLicitaciones> 
    ) 
[_SERVER] => Array 
    ( 
        [HTTP_HOST] => localhost 
        [HTTP_ACCEPT] => */* 
        [CONTENT_LENGTH] => 469 
        [CONTENT_TYPE] => application/x-www-form-urlencoded 
        [PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 
        [SERVER_SIGNATURE] => <address>Apache/2.2.22 (Fedora) Server at localhost Port 80</address> 
        [SERVER_SOFTWARE] => Apache/2.2.22 (Fedora) 
        [SERVER_NAME] => localhost 
        [SERVER_ADDR] => ::1 
        [SERVER_PORT] => 80 
        [REMOTE_ADDR] => ::1 
        [DOCUMENT_ROOT] => /var/www/html 
        [SERVER_ADMIN] => root@localhost 
        [SCRIPT_FILENAME] => /var/www/html/server.php 
        [REMOTE_PORT] => 37712 
        [GATEWAY_INTERFACE] => CGI/1.1 
        [SERVER_PROTOCOL] => HTTP/1.1 
        [REQUEST_METHOD] => POST 
        [QUERY_STRING] =>  
        [REQUEST_URI] => /server.php 
        [SCRIPT_NAME] => /server.php 
        [PHP_SELF] => /server.php 
        [PHP_AUTH_USER] => user 
        [PHP_AUTH_PW] => pass 
        [REQUEST_TIME] => 1343691710 
    ) 

)

我希望你能帮助我。

谢谢。

谨致问候。

我不确定500错误是否来自xml,但正如我在您的代码中看到的,xml没有url变量:

  myxml=<xml></xml>

因为你可以从响应中看到,url参数已经变成了

 [<?xml version] => "1.0" encoding="utf-8" ?> 

这是错误的。

如果api文档没有指定任何url参数,那么您可能应该设置正确的curl头:

 curl_setopt($ch,CURLOPT_HTTPHEADER, Array("Content-Type: application/xml"); 

像这样,服务器知道会发生什么

注意样本转储的这一部分:

  [_POST] => Array 
    ( 
        [<?xml version]

您的XML数据被解释为表单类型的数据上载,字段名为<?xml version。这破坏了XML的结构,导致您提交该文件的服务器上出现解析错误。

首先阅读下面的url,我认为这对你来说是非常有用的

将XML文件发送到Web服务(使用cURL)

http://softwaredevelopmentindia.wordpress.com/2007/07/09/sending-xml-files-to-a-webservice-using-curl/

或者试试这个

正在调用Web服务。非常有趣…当它工作时。最大的挑战之一是发送XML文档并返回响应,尤其是XML文档。我提出了一个PHP函数,它向用户隐藏所有必要的逻辑,并处理XML文档的发布,并返回服务器的任何响应。它依赖于PHP的cURL库(因此您需要在服务器上正确配置它才能工作)。您所需要做的就是创建XML文档,选择要将XML文档发布到的URL(和端口),然后由函数处理其余部分。下面是函数代码。正如您所看到的,该函数可以处理支持SSL的服务器,这提供了一个很大的优势,因为许多Web服务都在HTTPS上运行。

//打开http通道,传输数据并返回接收缓冲区

function xml_post($post_xml, $url, $port)
{
$user_agent = $_SERVER[’HTTP_USER_AGENT’];
$ch = curl_init(); // initialize curl handle
curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
curl_setopt($ch, CURLOPT_FAILONERROR, 1); // Fail on errors
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // allow redirects
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
curl_setopt($ch, CURLOPT_PORT, $port); //Set the port number
curl_setopt($ch, CURLOPT_TIMEOUT, 15); // times out after 15s
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_xml); // add POST fields
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
if($port==443)
{
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
}
$data = curl_exec($ch);
curl_close($ch);
return $data;
}

下面的示例通过发布形式的XML文档来显示该函数的工作方式

<?xml version=”1.0″ encoding=”iso-8859-1″?>
<Document> 
  <Message> 
     Your Name  
  </Message>
</Document>

到"listener"脚本,该脚本获取XML文档并返回回复(另一个XML文档)。在这种情况下,侦听器非常简单。它所做的只是将"Message"标记替换为"Reply",并打印生成的XML。当然,监听器可以做各种事情来响应POST。

<?php 
   if ( !isset( $HTTP_RAW_POST_DATA ) )
   {
      $HTTP_RAW_POST_DATA = file_get_contents( ‘php://input’ ); 
   } 
   $xml = str_replace(”Message”,”Reply” , $HTTP_RAW_POST_DATA);  
   print((trim($xml)));
?>