【问题标题】:Bad Request on PHP Curl request to SOAP web service对 SOAP Web 服务的 PHP Curl 请求的错误请求
【发布时间】:2019-03-04 02:16:52
【问题描述】:

这是我正在使用的方法:

$xml_data = 'XML data';

$headers = array(
"POST /ws_autos.asmx HTTP/1.1",
"Host: (web service url)",
"Content-Type: text/xml; charset=utf-8",
"SOAPAction: \"http://tempuri.org/(web service method)\"",
"Content-length: ".strlen($xml_data)
);

$url = (web service url)?wsdl;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);

$reply = curl_exec($ch); 



$xmli = new SimpleXMLElement($reply);


print_r($reply);

print_r($xmli);

我在执行时收到错误请求错误,但没有得到澄清。我检查了 XML 正文是否有错误,但似乎没有,据我所知,标题中没有任何不合适的地方。

我尝试过使用 SoapClient,但我找不到任何关于构建 XML 主体的文档/资源,这里有大量的嵌套。

【问题讨论】:

  • curl 不是套接字客户端,它们中的大多数标头都不起作用,并且 POSTFIELDS 期望的是数组或查询字符串而不是 XML 块
  • 我认为它可能会起作用,因为它被选为网站上另一个问题的答案,还因为我才刚刚开始学习一般的 SOAP 和 Web 服务,所以我不知道好的折扣。你知道我在哪里可以找到任何可以帮助我在这个特定问题上找到正确方向的文档吗?
  • 我会使用一个从 wsdl 生成模型的库,尽管有手动方法,google.com/search?q=soap+client+php+site:stackoverflow.com
  • @LawrenceCherone 实际上你错了,如果你希望你的 HTTP POST 正文是一个原始 XML 文件,然后将 XML 文件作为字符串发送到 CURLOPT_POSTFIELDS 并将 Content-Type 标头设置为 XML,他正确地完成了那部分。 - 只有当您想使用 Multipart/form-data-format 时,您才将 CURLOPT_POSTFIELDS 设置为数组

标签: php xml web-services curl soap


【解决方案1】:

您的 xml 已损坏,严格说。

DOMDocument::loadXML 是一个非常严格的 XML 解析器,它是这样说的: Warning: DOMDocument::loadXML(): XML declaration allowed only at the start of the document in Entity, line: 2 in /in/EOrYe on line 43

因为:

您的<?xml 声明不是您的XML 中的第一件事。您的 XML 中的第一件事是换行符,然后是您的 <?xml。您可以删除换行符,也可以替换

curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_data);

curl_setopt($ch, CURLOPT_POSTFIELDS, trim($xml_data));

也摆脱掉

"Content-length: ".strlen($xml_data)

因为如果你不这样做,libcurl 会自动为你添加它,并且 libcurl 不会犯任何错误(不像你,如果你这样做 curl_setopt($ch, CURLOPT_POSTFIELDS, trim($xml_data)); 那么长度会因为修剪而改变,所以差不多总是让 curl 为你做。)

也去掉"POST /ws_autos.asmx HTTP/1.1"

因为 1: curl 会为你添加这个标题。 和 2:你不知道 curl 是否会使用 HTTP/1.0 或 HTTP/1.1 或 HTTP/2 ,如果 curl 决定在这里使用 HTTP/2 ,你会破坏请求..(并且 curl 确实支持HTTP/2 现在,即使它需要 nginx 库 iirc 并且许多服务器的 curl 构建还不支持它,但是您不希望您的脚本在您的 curl 构建支持 HTTP/2 的那一刻神奇地停止工作,对吗?不,你不会。)

也去掉"Host: demo.caledoniaseguros.com.ar",

因为只要 url 正确,curl 就会为您添加它。几乎唯一需要(并且应该)手动设置 Host:-header 的时间是当您遇到 DNS 问题、您无法信任您的 DNS 或 DNS 查找时间太慢以至于您无法获得性能时命中,所有这些情况都极其罕见,而且大多数情况下只是一个菜鸟的错误。

【讨论】:

  • 很好地解释了,额外的信息非常受欢迎。谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-11-01
  • 1970-01-01
  • 2019-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-07
  • 2011-07-26
相关资源
最近更新 更多