2014-08-28 82 views
1

我使用R httr POST函数将jSON主体发送到API。该API正确地返回了302:Found消息,但是httr在我能够获取响应体(这是一个带有一些关键位信息的jSON体)之前正在退出函数。抑制302由httr POST返回的错误

正在运行HTTR使用详细(的)参数,下面是响应:

<- HTTP/1.1 302 Found 
<- Cache-Control: no-cache 
<- Pragma: no-cache 
<- Content-Length: 47 
<- Content-Type: application/json; charset=utf-8 
<- Expires: -1 
Error in function (type, msg, asError = TRUE) : 
    necessary data rewind wasn't possible 

我已经运行从终端一样卷曲后,可以证实什么,我把从同时与302的API产生的回复和期望的身体。

仅供参考我的R代码如下。 (注意:y是jSON格式的主体)

POST("https://thewebsite",authenticate("myusername","mypassword",type="basic"), 
    add_headers("Content-Type" = "application/json"), 
    body = y, verbose()) 

想法如何绕过错误和捕获302消息内容?

+0

好奇......会发生什么,如果你'PUT'代替'POST'?不意味着解决方案 - 仅用于故障排除。 – Deryck 2014-08-28 00:28:50

+0

GUT尝试一下,它显示它不是这个特定API的选项。产生“405:方法不允许”错误。 – TS4 2014-08-28 01:16:39

回答

1

我只是花了一些时间自己与这个问题作斗争。这个问题归结为HTTP规范(基本上RCurl坚持的是什么)和浏览器实际做的不同之处。

事件的顺序是这样的:

  1. 发出POST请求到服务器
  2. 服务器处理请求和问题,您重定向到新的URL
  3. RCurl对待这就像新的请求,就像一个POST ,并试图重播身体。 (浏览器不尝试并重新发送数据)
  4. 它不能重发数据,因为底层的RCurl不是以这种方式构建的(这就是curl抱怨的原因:“必要的数据倒带是不可能的“)

解决方法很简单 - 与config(followlocation = 0L)禁止重定向操作:

POST("https://thewebsite", 
    authenticate("myusername","mypassword"), 
    content_type_json(), 
    config(followlocation = 0L), 
    body = y, 
) 

# PS with httr 0.4 you can simplify to 
POST("https://thewebsite", 
    authenticate("myusername","mypassword"), 
    config(followlocation = 0L), 
    body = x, encode = "json" 
) 

然后您就需要考虑位置字段的内容,并执行重定向自己。

对于潜在的问题的更多讨论,请参见:

+0

'config(post = TRUE)'可能会在处理请求时解决问题,但如果没有可重复的示例,我无法确认 – hadley 2014-08-28 13:28:40

+0

辉煌,问题已解决! – TS4 2014-08-28 13:29:57

+0

@TS4是否使用'post = TRUE'而不是'followlocation = 0L'修复问题? – hadley 2014-08-28 16:49:39