【问题标题】:php curl and CURLOPT_FOLLOWLOCATION behaviorphp curl 和 CURLOPT_FOLLOWLOCATION 行为
【发布时间】:2016-03-03 10:28:40
【问题描述】:

情况是这样的。一方面,我们有一个带有 RESTful 服务的服务器。一种可能的查询是创建对象的 POST 查询。完成后,服务器会返回一个“Location”标头,以指示可以在何处找到有关新创建对象的信息。 但是,所述服务器对于每个请求都具有正确的 Content-Type 是非常重要的。例如,POST 需要 'application/json',而 GET 需要取消设置(有意义,因为 GET 没有正文)。

总而言之,我们有:

  • www.example.com/articles/;可以使用'Content-Type: application/json' 发送POST 请求,如果123 是新对象的id,服务器将返回'Location: www.example.com/articles/123'

  • www.example.com/articles/123;可以发送没有'Content-Type'GET 请求,服务器将返回新文章对象的描述。

在客户端,我们使用 PHPcURL。我们使用CURLOPT_FOLLOWLOCATIONsetting,所以我们可以读取新创建对象的描述。显然,我们还为我们的 POST 请求设置了'Content-Type: application/json'

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"name": "test"}');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_URL, "https://www.example.com/Articles/");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$result=curl_exec($ch);
var_dump($result);
curl_close ($ch);
?>

这是我们得到的:

string(101) "{ "errorNo": 415, "error": "Unsupported Media Type Content-Type should not be set in a GET request" }"

我查看了服务器的日志,确实,'Content-Type: application/json' 被发送到 GET www.example.com/articles/123

这是预期的行为吗?
如果是,那么最好的方法是什么:

  • 删除服务器端对 GET 请求的'Content-Type' 检查? (听起来很傻)
  • 忘记CURLOPT_FOLLOWLOCATION,并发出2 个明显分开的curl 请求,这样我就可以控制标题了吗? (但是CURLOPT_FOLLOWLOCATION 的意义何在?)
  • 还有别的吗?

为了控制和测试,我也使用Postman,我没有问题,它遵循位置,不会在GET部分(显然)之后发送'Content-Type'重定向,所以我没有错误。

编辑: PHP 文档中似乎没有什么有用的。但是我在命令行手册页中发现了一些有趣的东西:

https://curl.haxx.se/docs/manpage.html

上面写着:

"WARNING: headers set with this option will be set in all requests - even after redirects are followed, like when told with -L, --location."

所以我想这也可能是 PHP 的预期行为。那么有人可以建议最佳做法吗?

【问题讨论】:

  • 邮递区不应该是param1=val1&amp;... 格式吗?
  • 不一定;这个 API 例如理解 JSON
  • PHP 文档中似乎没有任何用处。但我在命令行手册页中发现了一些有趣的东西:curl.haxx.se/docs/manpage.html

标签: php curl http-headers content-type


【解决方案1】:

您是否尝试过使用

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");

设置帖子类型

【讨论】:

  • 是的,这迫使方法在重定向的请求上保持 POST,而不是变成 GET(这是我想要的),这意味着在 www 上使用“Content-Type: application/json”的 POST。 example.com/articles/123。这与我需要的相反。
猜你喜欢
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-25
  • 1970-01-01
相关资源
最近更新 更多