PHP curl 将 Content-Type 更改为 application/x-www-form-urlencoded。不应该那样做
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16079754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP curl changes the Content-Type to application/x-www-form-urlencoded. Shouldn't do that
提问by Johannes Klau?
I want to upload a video direct to Youtube from my server for which I am using PHP curl.
我想将视频从我使用 PHP curl 的服务器直接上传到 Youtube。
I need this request format:
我需要这个请求格式:
POST /feeds/api/users/default/uploads HTTP/1.1
Host: uploads.gdata.youtube.com
Authorization: Bearer ACCESS_TOKEN
GData-Version: 2
X-GData-Key: key=adf15ee97731bca89da876c...a8dc
Slug: video-test.mp4
Content-Type: multipart/related; boundary="f93dcbA3"
Content-Length: 1941255
Connection: close
--f93dcbA3
Content-Type: application/atom+xml; charset=UTF-8
<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:yt="http://gdata.youtube.com/schemas/2007">
<media:group>
<media:title type="plain">Bad Wedding Toast</media:title>
<media:description type="plain">
I gave a bad toast at my friend's wedding.
</media:description>
<media:category
scheme="http://gdata.youtube.com/schemas/2007/categories.cat">People
</media:category>
<media:keywords>toast, wedding</media:keywords>
</media:group>
</entry>
--f93dcbA3
Content-Type: video/mp4
Content-Transfer-Encoding: binary
<Binary File Data>
--f93dcbA3--
This is what I have:
这就是我所拥有的:
$content = $this->buildRequestContent();
$ch = curl_init();
$curlConfig = array(
CURLOPT_URL => 'http://uploads.gdata.youtube.com/feeds/api/users/default/uploads',
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_BINARYTRANSFER => true,
CURLOPT_POSTFIELDS => $content,
CURLOPT_HTTPHEADER, array(
"Authorization" => sprintf("GoogleLogin auth=%s", $this->accessToken),
"GData-Version" => 2,
"X-GData-Key" => sprintf("key=%s", $this->developerKey),
"Slug" => sprintf("%s", $this->video->getFilename()),
"Content-Type" => sprintf("multipart/related; boundary=\"%s\"", $this->boundaryString),
"Content-Length" => strlen($content),
"Connection" => "close"
),
);
curl_setopt_array($ch, $curlConfig);
$result = curl_exec($ch);
Dumping the result shows me that curl changed the Content-Type
to application/x-www-form-urlencoded
which is of course not supported by youtube.
倾销的结果让我发现,卷曲改Content-Type
到application/x-www-form-urlencoded
这当然不是由YouTube支持。
I put my binary content (the video) into CURLOPT_POSTFIELDS
, maybe this is wrong, but I don't know how to set the request body other than that.
我将我的二进制内容(视频)放入CURLOPT_POSTFIELDS
,也许这是错误的,但除此之外我不知道如何设置请求正文。
So how do I preserve my Content-Type that I set?
那么如何保留我设置的 Content-Type 呢?
采纳答案by Havelock
According to the documentation section regarding the options' parametersetting the HTTP method to POST
defaults to content type being set to application/x-www-form-urlencoded
. So my suspicion is that setting all the options at once, results in your Content-Type
being overwritten.
My suggestion would be to set the content type in a single statement, after you've set the method, i.e.
根据有关选项参数设置的文档部分,HTTP 方法POST
默认设置为内容类型application/x-www-form-urlencoded
。所以我怀疑一次设置所有选项会导致你Content-Type
被覆盖。
我的建议是在设置方法后在单个语句中设置内容类型,即
$curlConfig = array(
CURLOPT_URL => 'http://uploads.gdata.youtube.com/feeds/api/users/default/uploads',
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_BINARYTRANSFER => true,
CURLOPT_POSTFIELDS => $content,
);
curl_setopt_array($ch, $curlConfig);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: ' . sprintf('GoogleLogin auth=%s', $this->accessToken),
'GData-Version: 2',
'X-GData-Key: ' . sprintf('key=%s', $this->developerKey),
'Slug: ' . sprintf('%s', $this->video->getFilename()),
'Content-Type: ' . sprintf('multipart/related; boundary="%s"',
$this->boundaryString),
'Content-Length: ' . strlen($content),
'Connection: close'
));
回答by vbo
Accepted answer was not helpful for me and I found another problem in your code. According to the current PHP documentationCURLOPT_HTTPHEADER must be set like this:
接受的答案对我没有帮助,我在您的代码中发现了另一个问题。根据当前的 PHP文档CURLOPT_HTTPHEADER 必须像这样设置:
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-type: text/plain',
'Content-length: 100'
));
It must be a list of strings, not a hash like array('Content-Type' => 'text/plain')
.
Hope it will save someone's debugging time.
它必须是一个字符串列表,而不是像array('Content-Type' => 'text/plain')
. 希望它会节省某人的调试时间。