PHP Curl - 跟随“201 Created”响应头的位置

时间:2017-03-15 18:08:27

标签: php rest curl

我正在向API提交CURL Post请求,该请求在成功时返回状态“201 Created”,其中包含标题LOCATION部分中的资源URL。我想要的是自动检索新创建的资源,但到目前为止还没有这样做。我试过设置curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);但无济于事。值得注意的是资源确实需要GET请求。

我不确定状态代码是201,还是请求方法需要从POST更改为GET,但由于某种原因,它不会跟随{{1}标头提取LOCATION似乎确认了这一点,因为结果与原始网址相同,而不是新的curl_getinfo($ch,CURLINFO_EFFECTIVE_URL);

作为最后的手段,我考虑过简单地解析标题并创建一个新的CURL请求,但这不是最佳的,我猜我只是缺少一些简单的东西,使其按预期工作。

如何让CURL自动关注并向LOCATION提交{201}回复的GET请求?

2 个答案:

答案 0 :(得分:3)

你不能。

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);卷曲仅针对LOCATION状态代码的响应3xx

AFAIK并且作为文档说明没有办法强制卷曲跟随201响应的位置。

您必须解析标题,获取LOCATION,然后发出第二个curl请求。

在状态不同于3xx的位置之后将是异常。同样来自curl命令行工具和C库documentation-L, --location -- (HTTP) If the server reports that the requested page has moved to a different location (indicated with a Location: header and a 3XX response code), this option will make curl redo the request on the new place

快速查看/lib/http.c函数Curl_http_readwrite_headers上的curl源代码。

使用此条件处理位置跟随:

else if((k->httpcode >= 300 && k->httpcode < 400) &&
        checkprefix("Location:", k->p) &&
        !data->req.location) {
  /* this is the URL that the server advises us to use instead */
  char *location = Curl_copy_header_value(k->p);
  if(!location)
    return CURLE_OUT_OF_MEMORY;
  if(!*location)
    /* ignore empty data */
    free(location);
  else {
    data->req.location = location;

    if(data->set.http_follow_location) {
      DEBUGASSERT(!data->req.newurl);
      data->req.newurl = strdup(data->req.location); /* clone */
      if(!data->req.newurl)
        return CURLE_OUT_OF_MEMORY;

      /* some cases of POST and PUT etc needs to rewind the data
         stream at this point */
      result = http_perhapsrewind(conn);
      if(result)
        return result;
    }
  }
}

该位置后面的状态代码介于300399

之间

答案 1 :(得分:0)

我理解这并不是纯粹意义上的回答你的问题 - 我的解决方案甚至不在PHP中,但这是一种方式(使用jq)跟随201跟cURL:

class Subject: Day {
    var subjectName: String
    var startsAt: String?
    init(dayName: String,subjectName: String) {
        self.subjectName = subjectName
        super.init(dayName: dayName)
    }

    required convenience init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


}

我今天把这个放在一起进行类似的研究,并认为我在寻找选择时遇到了这个问题。

可以很容易地调整使用sed或类似代码而不是jq来解析http 201标头响应,其中我正在解析由tinypng提供的http体json响应(仅用于参考 - 我不隶属于它们)