【发布时间】: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 请求,服务器将返回新文章对象的描述。
在客户端,我们使用 PHP 和 cURL。我们使用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&...格式吗? -
不一定;这个 API 例如理解 JSON
-
PHP 文档中似乎没有任何用处。但我在命令行手册页中发现了一些有趣的东西:curl.haxx.se/docs/manpage.html
标签: php curl http-headers content-type