php curl和CURLOPT_FOLLOWLOCATION行为

Here's the situation. On one side, we have a server, with a RESTful service. One possible query to it is a POST query to create an object. When that is done, the server returns a 'Location' header, to indicate where information on the newly created object can be found. However, said server is anal about having the correct Content-Type for each request. For instance, POST requires 'application/json', and GET requires this to be unset (make sense, since GET doesn't have a body).

To sum up, we have:

  • www.example.com/articles/ ; one can send a POST request with 'Content-Type: application/json', and server will return 'Location: www.example.com/articles/123' if 123 is the id of the new object ;

  • www.example.com/articles/123 ; one can send a GET request with no 'Content-Type' and server will return a description of the new article object.

On client side, we use PHP with cURL. We use the CURLOPT_FOLLOWLOCATIONsetting so we can read the description of the newly created object. Obviously, we also set 'Content-Type: application/json' for our POST request:

<?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);
?>

This is what we get:

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

I looked at the log of the server, and indeed, 'Content-Type: application/json' is sent to GET www.example.com/articles/123.

Is this an expected behaviour?
If yes, what is then best approach:

  • remove the 'Content-Type' check on GET requests, server-side? (sounds silly)
  • forget about CURLOPT_FOLLOWLOCATION, and make 2 clearly separated curl requests, so I have control over the headers? (but then what's the point of CURLOPT_FOLLOWLOCATION?)
  • something else?

For control and testing, I also use Postman, and I have no problem with it, it follows the location, doesn't send the 'Content-Type' on the GET part (apparently) after the redirection and so I don't have an error.

EDIT: There seems to be nothing useful in the PHP doc. But I found something interesting in the command line man page:

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

It says:

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

So I guess it probably is the expected behaviour for PHP too. May someone suggest best practices then?

dongqu9972
dongqu9972 在PHP文档中似乎没有任何用处。但是我在命令行手册页中找到了一些有趣的东西:curl.haxx.se/docs/manpage.html
4 年多之前 回复
dongyonglie5132
dongyonglie5132 不必要;例如,此API了解JSON
4 年多之前 回复
dszm02606009
dszm02606009 postfields不应该是param1=val1&...格式吗?
4 年多之前 回复

1个回答



您是否尝试过使用</ p>

curl_setopt($ ch,CURLOPT_CUSTOMREQUEST,“POST”); </ p>

设置帖子类型</ p>
</ div>

展开原文

原文

Have you tried using

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

to set the post type

duancaishi1897
duancaishi1897 是的,这迫使该方法在重定向的请求上保持POST,而不是成为GET(这是我想要的),这意味着在www.example.com/articles/123上使用“Content-Type:application / json”进行POST。 这与我的需要相反。
4 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问