Запрос API httr POST, но отсутствует параметр xml

Я пытаюсь подключиться к XML API для IBM Silverpop с помощью httr, но столкнулся с проблемой «отсутствует параметр XML». Я попытался использовать тестовую систему, предоставленную Silverpop, чтобы увидеть, отличаются ли запросы, которые я отправляю, по сравнению с теми, которые я отправляю через httr, но не нашел ничего, что могло бы мне помочь.

Ниже приведен текст XML, который я отправляю при успешном использовании тестового набора:

<Envelope><Body>
<Login>
<USERNAME>My Email</USERNAME>
<PASSWORD>My password</PASSWORD>
</Login>
</Body></Envelope>

Использование Chrome для проверки заголовков запроса (используя CTRL + SHIFT + I):

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:225
Content-Type:application/x-www-form-urlencoded
Host:api3.silverpop.com
Origin:null
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36

Опять же, используя Chrome для проверки заголовков ответа:

Connection:Keep-Alive
Content-Type:text/xml;charset=utf-8
Date:Fri, 04 Dec 2015 12:15:34 GMT
Keep-Alive:timeout=15, max=100
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked

Используя httr, я строю свой запрос следующим образом:

library(httr)

ibmUrl <- "api3.silverpop.com/XMLAPI"

body1 <- "<Envelope><Body>
<Login>
<USERNAME>My Email</USERNAME>
<PASSWORD>My password</PASSWORD>
</Login>
</Body></Envelope>"

test1 <- POST(url = ibmUrl, body = body1, verbose(), content_type("application/x-www-form-urlencoded"))

Использование verbose() показывает отправку и получение следующего:

-> POST /XMLAPI HTTP/1.1
-> Host: api3.silverpop.com
-> User-Agent: libcurl/7.43.0 r-curl/0.9.3 httr/1.0.0
-> Accept-Encoding: gzip, deflate
-> Accept: application/json, text/xml, application/xml, */*
-> Content-Type: application/x-www-form-urlencoded
-> Content-Length: 132
-> 
>> <Envelope><Body>
>> <Login>
>> <USERNAME>My Email</USERNAME>
>> <PASSWORD>My password</PASSWORD>
>> </Login>
>> </Body></Envelope>

<- HTTP/1.1 200 OK
<- Date: Fri, 04 Dec 2015 13:29:55 GMT
<- Server: Apache-Coyote/1.1
<- Content-Type: text/xml
<- Content-Length: 255

Но когда я проверяю ответ API с помощью content(), я получаю следующее:

<?xml version="1.0"?>
<Envelope>
  <Body>
    <RESULT>
      <SUCCESS>false</SUCCESS>
    </RESULT>
    <Fault>
      <Request/>
      <FaultCode/>
      <FaultString>Missing 'xml'parameter</FaultString>
      <detail>
        <error>
          <errorid>52</errorid>
          <module/>
          <class>SP.API</class>
          <method/>
        </error>
      </detail>
    </Fault>
  </Body>
</Envelope>

Почему?

Заранее спасибо.


person info_seekeR    schedule 04.12.2015    source источник


Ответы (1)


Я думаю, что нашел ответ - хотя не совсем уверен, почему это работает, и моя первоначальная попытка, показанная в вопросе, не сработала...

Это был мой исходный код:

test1 <- POST(url = ibmUrl, body = body1, 
verbose(), content_type("application/x-www-form-urlencoded"))

Все, что мне нужно было изменить, это content_type на «text/xml».

test1 <- POST(url = ibmUrl,
        body = body1, verbose(), content_type("text/xml"))

И это работает... Но было бы благодарно, если бы кто-нибудь откликнулся и объяснил, почему это решает проблему...

person info_seekeR    schedule 04.12.2015
comment
@hadley (смущенно), но я копировал только необработанную форму запроса, отправляемого моим браузером. Я думал, что то же самое будет отправлено с помощью httr? Спасибо за ответ. - person info_seekeR; 05.12.2015
comment
Я знаю, что это старо, но я только что наткнулся на очень похожую проблему, и оказалось, что они, похоже, принимают только текст/xml, а не приложение/xml. Таким образом, content_type_xml() не работает с любопытным сообщением об ошибке, в котором отсутствует параметр xml :) - person DeVadder; 14.07.2016
comment
Кроме того, чтобы ответить на вопрос здесь, прямо из xml_api_developer_guide для Silverpop: при передаче XML в качестве параметра URL-адреса (xml=) вы должны кодировать URL-адрес XML и указывать, что он кодируется URL-адресом (тип содержимого: application/x-www -form-urlencoded). Поэтому я предполагаю, что это то, что делает testharness. - person DeVadder; 14.07.2016
comment
@DeVadder вопрос был старым, но информация, которой вы поделились, безусловно, ценна - спасибо! - person info_seekeR; 09.08.2016
comment
@info_seekeR Да, но люди будущего все еще могут наткнуться на него и задаться тем же вопросом. И шесть месяцев на самом деле не так уж и много, особенно если учесть, что наши повелители Silverpop ничего не меняли ни в API, ни в его документации за это время. - person DeVadder; 02.09.2016
comment
Вау, это спасло мой день. Даже я застрял в той же проблеме, хотя я пытался использовать php. Все, что я изменил, это application/xml на text/xml. Большое спасибо @info_seekeR - person Prabodh M; 28.06.2017