我们正在尝试将我们的magento安装与第三方库存管理应用程序(基于.net构建)连接起来。但同步不起作用,第三方告诉我,soap api正在返回空响应。
我一直在聆听我的声音,因为每当我在PHP中制作任何东西时,API工作正常。此外,库存更新工作正常,但检索订单/发票信息却没有(实际上偶尔会有1%的时间检索)
由于间歇性,我们觉得它一定是网络问题,但经过大量搜索并将mage :: log()添加到核心api文件后,我可以看到连接正在发生,而且响应对象更多由Magento创建。
所以我的推论是因为SOAP API(我使用的是版本2)不正确
我已经安装了soapUI并设置了我们的集成,它正确地从WSDL文件接收方法但是当我尝试访问“login”方法时,我得到一个空响应,即使我输入了错误的登录详细信息它是空的
soapUI输出以下错误:
错误:发生错误[Content-Length分隔邮件正文的过早结束(预期:267;已收到:266),有关详细信息,请参阅错误日志
因此似乎http头部存在问题,一些函数能够返回响应(当然没有登录哈希它只是无效,但至少它是一个响应)。从我(非常有限)对java和.net的理解来看,他们对这些东西比php更严格,这表明为什么php集成没有问题。
任何人都可以告诉我为什么会出现这个错误以及如何修复它?
答案 0 :(得分:3)
我将假设您正在使用符合WS-I的SOAP API v2,因为我有完全相同的问题;如果没有,那么这仍然可能适用。如果没有符合WS-I标准,我就无法连接到v2 API,这就是我发现这个错误的方法。
如果你看一下你将在公共运行函数中看到的app/code/core/Mage/Api/Model/Server/Wsi/Adapter/Soap.php
文件,它基本上分为两部分 - 一部分用于WSDL定义响应,一部分用于实际的SOAP响应。
在SOAP响应中,有一些字符串替换正在进行,用<soap:operation soapAction=""></soap:operation>
代替<soap:operation soapAction="" />
,依此类推。这显然会导致内容长度计算出现问题 - 这也发生在WSDL定义响应中,但它似乎没有引起问题。
通过使用下面的代码替换try花括号之间的代码,我能够成功连接到SOAP API。基本上,我最后清除标题并重新计算内容长度 AFTER 更换字符串:
$this->_instantiateServer();
$content = preg_replace(
'/(\>\<)/i',
">\n<",
str_replace(
'<soap:operation soapAction=""></soap:operation>',
"<soap:operation soapAction=\"\" />\n",
str_replace(
'<soap:body use="literal"></soap:body>',
"<soap:body use=\"literal\" />\n",
preg_replace(
'/<\?xml version="([^\"]+)"([^\>]+)>/i',
'<?xml version="$1" encoding="'.$apiConfigCharset.'"?>',
$this->_soap->handle()
)
)
)
);
$this->getController()->getResponse()
->clearHeaders()
->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
->setHeader('Content-Length',strlen($content))
->setBody($content);
希望这有帮助
答案 1 :(得分:2)
如果您使用的是V2版本,则需要更改:
/app/core/Mage/Api/Model/Server/V2/Adapter/Soap.php
关于第62行将try{}
的内容替换为:
$this->_instantiateServer();
$content = preg_replace(
'/<\?xml version="([^\"]+)"([^\>]+)>/i',
'<?xml version="$1" encoding="'.$apiConfigCharset.'"?>',
$this->_soap->handle()
);
$this->getController()->getResponse()
->clearHeaders()
->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
->setHeader('Content-Length',strlen($content))
->setBody($content);
这对我来说并没有解决所有问题,有一些神秘的空白实例搞砸了所有东西,一个是关闭标签之后的空间,另一个是客户在电话号码末尾添加了两个空格(??)
无论如何要清除这两个我做的......
这对我来说没有解决所有问题,还有一些空白问题,我添加了一些额外的preg_replace以便快速修复它
$content = preg_replace('/\s+/', ' ', $content);
$content = preg_replace('/Envelope> /', 'Envelope>', $content);
答案 2 :(得分:0)
对我有用的唯一解决方案是将API端点切换为NOT使用index.php
变化来自:
domain.com/index.php/api/v2_soap/index/wsdl/1
于:
domain.com/api/v2_soap/?wsdl=1
注意从url中删除了index.php。这样,请求将通过api.php入口点而不是index.php。 作为一个有效的方面,api开始工作得更快,因为api.php更轻巧。
在浏览器中打开WSDL(domain.com/api/v2_soap/?wsdl=1)并验证它是否正确。 soap:address节点不应包含index.php部分:
<soap:address location="http://domain.com/api.php/?type=v2_soap"/>
在客户端脚本中使用domain.com/api/v2_soap/?wsdl=1网址
location /api {
rewrite ^/api/rest /api.php?type=rest last;
rewrite ^/api/v2_soap /api.php?type=v2_soap last;
rewrite ^/api/soap /api.php?type=soap last;
}
取消注释行:
RewriteRule ^api/([a-z][0-9a-z_]+)/?$ api.php?type=$1 [QSA,L]
我正在研究Magento 1.9.2.4