3

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

使用 Verbose() 参数运行 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

我已经从终端运行了相同的 cURL 帖子,并且可以确认我发送的内容会产生来自 API 的回复,其中包含 302 和所需的正文。

作为参考,我的 R 代码如下。(注意:y 是 JSON 格式的正文)

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

关于如何绕过错误并捕获 302 消息内容的任何想法?

4

1 回答 1

3

我自己只是花了一些时间来解决这个问题。问题归结为 HTTP 规范(基本上是 RCurl 所遵循的)和浏览器实际执行的操作之间的差异。

事件的顺序是这样的:

  1. 您向服务器发出 POST 请求
  2. 服务器处理请求并向您发出重定向到新网址
  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" 
)

然后,您需要查看位置字段的内容,并自己进行重定向。

有关潜在问题的更多讨论,请参阅:

于 2014-08-28T13:03:52.613 回答