【问题标题】:PHP curl changes the Content-Type to application/x-www-form-urlencoded. Shouldn't do thatPHP curl 将 Content-Type 更改为 application/x-www-form-urlencoded。不应该那样做
【发布时间】:2013-04-18 09:52:40
【问题描述】:

我想从我正在使用 PHP curl 的服务器将视频直接上传到 Youtube。

我需要这种请求格式:

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--

这就是我所拥有的:

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

转储结果显示 curl 将 Content-Type 更改为 application/x-www-form-urlencoded,这当然不受 youtube 支持。

我将我的二进制内容(视频)放入CURLOPT_POSTFIELDS,可能这是错误的,但我不知道如何设置请求正文。

那么如何保留我设置的 Content-Type?

【问题讨论】:

  • 根据文档CURLOPT_POSTContent-Type 自动设置为application/x-www-form-urlencoded。尝试在单个语句中设置此选项和CURLOPT_HEADER,或者至少在单个语句中使用curl_setopt 在设置方法之后设置后者。
  • 工作。您能否将此作为答案发布,以便我接受?

标签: php curl http-headers


【解决方案1】:

接受的答案对我没有帮助,我在您的代码中发现了另一个问题。根据目前PHP的documentationCURLOPT_HTTPHEADER必须这样设置:

curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-type: text/plain',
    'Content-length: 100'
));

它必须是一个字符串列表,而不是像array('Content-Type' =&gt; 'text/plain') 这样的散列。 希望它可以节省某人的调试时间。

【讨论】:

  • 换句话说,您不能将关联数组传递给 CURLOPT_HTTPHEADER,只能传递简单数组。这个问题让我发疯了好几个小时......
【解决方案2】:

根据documentation section regarding the options' parameter将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'
));

【讨论】:

  • 请更新您的示例,它不是二维数组。应该是:array("Authorization:" .sprintf..., "Content-Type:" .sprintf....)
  • @JohnCongdon:正确,谢谢!有趣的是,在短短两年多的时间里,没有人注意到它,三个赞成票和“接受的答案”。 (我确定您的意思是“不是关联数组”而不是“不是二维数组”;))
  • 为 PHP cURL 感到羞耻。不仅CURLOPT_POST 覆盖Content-Type,而且防止同时设置其他HTTP 标头。感谢您的解决方案!
  • 我无法使用此解决方案。我已经将标题的设置与其余选项分开,它仍然添加了额外的内容类型。
  • @dmarra 我建议只使用像 GuzzleHttp 这样的专用客户端库
猜你喜欢
  • 2019-10-26
  • 1970-01-01
  • 2019-05-24
  • 2019-02-04
  • 1970-01-01
  • 2013-11-10
  • 2018-12-27
  • 2018-05-12
  • 2018-06-20
相关资源
最近更新 更多