没有收到通过PHP发送的XML

时间:2011-10-13 18:29:31

标签: php xml post http-headers

我正在使用BlueHornet API发送电子邮件,特别是 legacy.send_campaign 方法。我正在更新客户端现有的API调用,并已被指示

  

“使用下面指定的参数发布XML消息。确保包含< send>元素并将其值设置为'Y'.POST响应消息将包含< message_id>元素和< message_key&gt ;元素。

这是提供的格式:

<api>
    <authentication>
        <api_key>ClientAPIKey</api_key>
        <shared_secret>ClientSharedSecret</shared_secret>
        <response_type>xml</response_type>
    </authentication>
    <data>
        <methodCall>
            <methodName>legacy.send_campaign</methodName>
            <grp>ClientEmailGroupCode</grp>
            <rich_mbody><![CDATA[<html...LONG HTML BLOCK...</html>]]></rich_mbody>
            <text_mbody><![CDATA[...LONG TEXT BODY...]]></text_mbody>
            <reply_email>ClientReplyEmail</reply_email>
            <from_email>ClientFromEmail</from_email>
            <fromdesc>ClientFromName</fromdesc>
            <msubject>ClientEmailSubject</msubject>
            <send>Y</send>
            <track_links>1</track_links>
        </methodCall>
    </data>
</api>

API受密码保护,但我可以根据要求发布文档。

我已确认 ClientAPIKey ClientSharedSecret ClientEmailGroupCode 有效,但我的测试未成功。发送以下内容(使用 fsockopen() FWIW):

POST /api/xmlrpc/index.php HTTP/1.0
Host: echoN.bluehornet.com
Content-Type: text/xml;charset=utf-8
Content-Length: 21551

<?xml version="1.0"?>
<api>
    <authentication>...as above...</authentication>
    <data>...as above...</data>
</api>

导致第三方服务器发回该XML响应,指示错误:

HTTP/1.1 200 OK
Date: Thu, 13 Oct 2011 13:18:50 GMT
Server: Apache/1.3.41 (Unix)
Cache-Control: max-age=18000
Expires: Thu, 13 Oct 2011 18:18:50 GMT
Connection: close
Content-Type: text/xml;charset=utf-8
Set-Cookie: BIGipServerBH-gen-80=387268618.20480.0000; path=/

<!--?xml version="1.0" encoding="utf-8"?-->
<methodresponse><item><error><!--[CDATA[1]]--></error>
<responsetext><!--[CDATA[No XML Data Passed.]]--></responsetext>
<responsedata><responsenum><!--[CDATA[1]]--></responsenum>
<totalrequests><!--[CDATA[0]]--></totalrequests>
<totalcompleted><!--[CDATA[0]]--></totalcompleted>
</responsedata></item></methodresponse>
为了便于阅读,添加了

换行符。

“没有XML数据通过”的responseText。关注我,所以我联系了供应商并被告知要仔细检查我的网址(http与https,在echo * N *。bluehornet ...等中纠正N)并确保我发布了“数据”参数。建议将“?data =”放在HTTP标头中查询URL的末尾:

POST /api/xmlrpc/index.php?data= HTTP/1.0

或将“data =”添加到请求正文中的XML块:

data=<?xml version="1.0"?>

似乎是为.NET姐妹项目编写的代码所暗示的:

private void ConstructData()
{
    data.Append("data=");
    data.Append("<api>");
    data.Append("<authentication>");
    data.Append(authenticationData.ToString());
    data.Append("</authentication>");
    data.Append("<data><methodCall>");
    data.Append(methodCallData.ToString());
    data.Append("</methodCall></data>");
    data.Append("</api>");
}

修改查询URL无效,在XML块之前放置“data =”会导致加载时间延长,无服务器响应。

此时,供应商正在尝试挖掘使用此API的开发人员,以便权衡问题。与此同时,我认为我会分享上述内容,看看是否有人可以指出任何问题 - 可能是轻微的疏忽或明显的遗漏 - 这可能导致我的XML数据无法发送。

4 个答案:

答案 0 :(得分:2)

如果post真的应该看起来像data = xxx那么你应该用这个标题发送帖子数据

Content-Type: application/x-www-form-urlencoded

对于帖子身体,嗯,url编码:)

答案 1 :(得分:1)

这很有效。到底有没有时间来到这里。最后意识到?data =是传递有效载荷的字段。

import urllib

from google.appengine.api import urlfetch

url = "https://echoN.bluehornet.com/api/xmlrpc/index.php"


    XML="""<api>
    <authentication>
    <api_key>000000000000000000</api_key>
    <shared_secret>00000000</shared_secret>
    <response_type>xml</response_type>
    </authentication>
    <data>
    <methodCall>
    <methodName>legacy.retrieve_active</methodName>
    <email>me@me.com</email>
    <return_groups>1</return_groups>
    </methodCall>
    </data>
    </api>"""


form_fields = {'data': XML}
form_data = urllib.urlencode(form_fields)

result = urlfetch.fetch(url=url,
                        payload=form_data,
                        method=urlfetch.POST,
                        headers={'Content-Type': 'application/x-www-form-urlencoded'})

print result.content

答案 2 :(得分:1)

当我删除标题行时,它会起作用:

//curl_setopt($ch, CURLOPT_HTTPHEADER, ...

最终代码:

curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('data' => $xml));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);

答案 3 :(得分:0)

使其工作的唯一方法是POST XML as byte array with content-type =“application / x-www-form-urlencoded”