cURL 不发送内容长度

cURL not sending content-length

我正在尝试从 Spotify API 获取 O-Auth 令牌,但是在 Debian 8 上使用 cURL 时,在我的 MacBook 上运行时,我总是收到错误消息 POST requests require a Content-length header.

$authString = $spotifyId . ":" . $spotifySecret;
$encodedAuthString = base64_encode($authString);

$spotifyHeaders = array(
    "Authorization: Basic " . $encodedAuthString,
    "Content-Type: application/x-www-form-urlencoded",
);

$spotifyOauthCurl = curl_init();
curl_setopt($spotifyOauthCurl, CURLOPT_URL, "https://accounts.spotify.com/api/token");
curl_setopt($spotifyOauthCurl, CURLOPT_POST, true);
curl_setopt($spotifyOauthCurl, CURLOPT_HTTPHEADER, $spotifyHeaders);
curl_setopt($spotifyOauthCurl, POSTFIELDS, "grant_type=client_credentials");
curl_setopt($spotifyOauthCurl, CURLOPT_RETURNTRANSFER, true);
// curl_setopt($spotifyOauthCurl, CURLINFO_HEADER_OUT, true);
$result = curl_exec($spotifyOauthCurl);
echo curl_getinfo($spotifyOauthCurl, CURLINFO_HEADER_OUT);

按照@hanshenrik 的建议添加CURLOPT_VERBOSE 返回以下输出

Trying 35.186.224.25...
* TCP_NODELAY set
* Connected to accounts.spotify.com (35.186.224.25) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=SE; L=Stockholm; O=Spotify AB; CN=*.spotify.com
*  start date: May  3 00:00:00 2021 GMT
*  expire date: May  3 23:59:59 2022 GMT
*  subjectAltName: host "accounts.spotify.com" matched certs "*.spotify.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
*  SSL certificate verify ok.
> POST /api/token HTTP/1.1

/api/token?grant_type=client_credentials HTTP/1.1
Host: accounts.spotify.com
Accept: */ *
Authorization: Basic ...
Content-Type: application/x-www-form-urlencoded
Expect: 100-continue

* HTTP 1.0, assume close after body
< HTTP/1.0 411 Length Required
< Content-Type: text/html; charset=UTF-8
< Referrer-Policy: no-referrer
< Content-Length: 1564
< Date: Wed, 26 Jan 2022 17:36:23 GMT
< 
* Curl_http_done: called premature == 0
* Closing connection 0

1:您忽略了错误日志,每次 运行

curl_setopt($spotifyOauthCurl, POSTFIELDS, "grant_type: client_credentials");

您的错误日志收到类似

的消息
Warning: Use of undefined constant POSTFIELDS - assumed 'POSTFIELDS' (this will throw an Error in a future version of PHP) in /in/S9fsj on line 3
string(10) "POSTFIELDS"

另外你是 运行宁 php 5/7,因为在 PHP8 这会抛出异常:https://3v4l.org/S9fsj

2:您忽略了 curl_setopt return 错误,curl_setopt returns false 错误,您的代码忽略了这些错误。一个简单的方法是

function ecurl_setopt ( /*resource*/$ch , int $option , /*mixed*/ $value ){
    $ret=curl_setopt($ch,$option,$value);
    if($ret!==true){
        //option should be obvious by stack trace
        throw new RuntimeException ( 'curl_setopt() failed. curl_errno: ' .  curl_errno ($ch) .'. curl_error: '.curl_error($ch) );
    }
}

3:都是错别字造成的!它应该是 CURLOPT_POSTFIELDS 而不仅仅是 POSTFIELDS