我们正在努力为我们的Magento安装与第三方库存管理应用程序(建立在.NET)连接。 但是,是不是工作同步,第三方告诉我,SOAP API则返回一个空的响应。
我一直在拉我听得出来,因为每当我在PHP做任何事情的API工作正常。 除了库存更新工作正常,但检索订单/发票信息不(以及它实际上偶尔1%的时间)
随着间歇性,我们认为,这必须是一个网络问题,但很多搜索和添加法师::日志()为核心API的文件后,我可以看到连接正在发生的事情,还更是由创建的响应对象Magento的。
所以,我扣为东西是不正确的使用SOAP API(我用第2版)
我已经安装的soapUI和设置我们的集成,它正确地从WSDL文件接收方法,但是当我试图访问“登录”的方法,我得到一个空的响应,甚至当我把不正确的登录信息是空的。
的soapUI输出如下错误:
错误:发生错误[Content-Length的分隔消息体(预期的过早结束:267;接收:266],参见错误日志细节
因此,它好像有一个与HTTP标头的问题,有些功能能够返回响应(当然没有登录散列它仅仅是无效的,但至少这是一个响应)。 从Java和.NET的我(非常有限)的理解,他们对这些东西比PHP这将说明为什么PHP集成就没有问题,更严格。
谁能告诉我,为什么会出现这种错误,以及如何解决它?
我会假设你使用的是WS-I标准的SOAP API V2作为我有此相同的问题; 如果没有,那么这可能仍然适用。 我从来没有能够连接到V2 API没有它符合WS-I,这是我发现了这个错误。
如果你看一下app/code/core/Mage/Api/Model/Server/Wsi/Adapter/Soap.php
文件,你会在本质上是分成两个部分的公共运行功能看- 1的WSDL定义响应,1个用于实际SOAP响应。
在SOAP响应有一个位串置换发生的情况,用<soap:operation soapAction=""></soap:operation>
为<soap:operation soapAction="" />
等。 这显然是造成问题与内容长度的计算 - 这也是发生在WSDL定义响应,但它似乎并没有会造成问题。
我可以用下面的代码替换尝试大括号中的代码成功地连接到SOAP API。 基本上,我结束了清除页眉和重新计算的内容长度后面的字符串替换已经发生:
$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);
希望这可以帮助
作为参考,如果您正在使用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);
这didin't解决一切对我来说,有神秘空白的一些实例被拧紧了一切,一个是结束标记后面输入一个空格,另一种是当客户增加了两个空间上他们的电话号码(结束? )
反正以清除这两个我没有...
这并没有解决我的一切,仍然有一些空白的问题,我为了快速解决问题增加了一些额外的preg_replace
$content = preg_replace('/\s+/', ' ', $content);
$content = preg_replace('/Envelope> /', 'Envelope>', $content);
这工作对我来说,唯一的解决办法是切换API端点不使用的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更轻巧。
采取的步骤:
- 请确保您有nginx的或的.htaccess(见下文)设置正确的重定向规则
- 明确的Magento缓存
在浏览器(domain.com/api/v2_soap/?wsdl=1)开放WSDL,并验证它是否正确。 肥皂:地址节点不应该包含index.php的一部分:
<soap:address location="http://domain.com/api.php/?type=v2_soap"/>
使用domain.com/api/v2_soap/?wsdl=1网址在您的客户端脚本
Nginx的配置:
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;
}
阿帕奇的.htaccess:
取消注释行:
RewriteRule ^api/([a-z][0-9a-z_]+)/?$ api.php?type=$1 [QSA,L]
其他的解决方案,没有工作,形成了我:
- 编辑V2 /适配器/ Soap.php
- 编辑WSI /适配器/ Soap.php
我工作的Magento 1.9.2.4