【问题标题】:Magento Soap API V2 Response Content Length IncorrectMagento Soap API V2 响应内容长度不正确
【发布时间】:2012-09-29 08:14:39
【问题描述】:

我们正在尝试将我们的 magento 安装与第三方库存管理应用程序(基于 .net)连接起来。但是同步不起作用,第三方告诉我soap api正在返回一个空响应。

我一直在倾听,因为每当我用 PHP 做任何事情时,API 都可以正常工作。此外,库存更新工作正常,但检索订单/发票信息却不行(实际上它偶尔会在 1% 的时间里这样做)

由于间歇性,我们认为这一定是网络问题,但经过大量搜索并将 mage::log() 添加到核心 api 文件中,我可以看到连接正在发生,并且响应对象是由 Magento 创建。

所以我的推断是 SOAP API 有问题(我使用的是版本 2)

我已经安装了soapUI并设置了我们的集成,它正确地接收来自WSDL文件的方法但是当我尝试访问“登录”方法时我得到一个空响应,即使我输入了不正确的登录详细信息它也是空的.

soapUI 输出如下错误:

错误:发生错误[Premature end of Content-Length delimited message body (expected: 267; received: 266],详见错误日志

因此,似乎 http 标头存在问题,某些函数能够返回响应(当然,如果没有登录哈希,它只是无效的,但至少它是一个响应)。根据我对 java 和 .net 的(非常有限的)理解,它们在这些方面比 php 严格得多,这表明为什么 php 集成不会有任何问题。

谁能告诉我为什么会发生这个错误以及如何解决它?

【问题讨论】:

标签: api magento soap magento-1.7


【解决方案1】:

对我有用的唯一解决方案是将 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 缓存
  • 在浏览器中打开 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 网址

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;
}

Apache .htaccess:

取消注释行:

RewriteRule ^api/([a-z][0-9a-z_]+)/?$ api.php?type=$1 [QSA,L]

其他对我不起作用的解决方案:

  • 编辑V2/Adapter/Soap.php
  • 编辑 Wsi/Adapter/Soap.php

我正在开发 Magento 1.9.2.4

【讨论】:

    【解决方案2】:

    我假设您使用的是符合 WS-I 的 SOAP API v2,因为我遇到了同样的问题;如果不是,那么这仍然可能适用。在不符合 WS-I 的情况下,我永远无法连接到 v2 API,这就是我发现这个错误的原因。

    如果您查看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 定义响应中,但似乎不会导致问题。

    通过将 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);
    

    希望对你有帮助

    【讨论】:

    • 非常感谢,我使用的是 v2,所以我不得不更改另一个文件。不幸的是,我仍然遇到同样的问题,一个字节仍然丢失,还有其他地方可以更改正文吗?
    • 顺便说一句,目前的快速解决方法是 ->setHeader('Content-Length',strlen($content)-1)
    • @Zyava - 很可能,我没有在我的 cmets 中输入链接(我通常出于这个确切原因这样做)并且一年多前我遇到了问题
    • 我将此标记为正确答案,我使用的是 v2 API,因此作为参考,我将在下面创建一个答案,其中包括针对该情况的修复。我的所有请求都超出了 1 个字节,因此 -1 修复对我来说效果很好,我无法理解那个字节的去向,但我在生活中有更重要的事情。
    【解决方案3】:

    如果您正在使用需要更改的 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);
    

    【讨论】:

      猜你喜欢
      • 2017-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      • 2013-07-16
      • 1970-01-01
      • 2012-03-25
      • 1970-01-01
      相关资源
      最近更新 更多