PHP7 CURL发送POST请求遇Google API编码报错,如何适配?
解决Google API JSON POST请求编码问题
嘿,这个问题我之前帮不少开发者踩过坑!Google API明确要求请求体采用纯JSON格式,你的代码思路是对的,但几个小细节没处理到位,导致CURL还是默认用了表单编码的逻辑,才触发了"This API does not support parsing form-encoded input."的报错。
问题根源
虽然你设置了Content-Type: application/json,但有两个潜在问题可能导致请求不符合要求:
- 手动设置的
Content-Length可能计算错误(比如遇到多字节UTF-8字符时,虽然PHP的json_encode()输出UTF-8字符串,strlen()能拿到正确字节数,但让CURL自动计算更稳妥); - 部分CURL版本中,即使传递字符串给
CURLOPT_POSTFIELDS,若没有明确约束行为,可能仍会被误识别为表单数据。
修正后的代码
直接给你调整好的代码,关键修改点我标了注释:
$json = json_encode($data); // 先确认JSON编码是否成功,避免空请求或无效格式 if ($json === false) { throw new Exception('JSON编码失败: ' . json_last_error_msg()); } curl_setopt_array($this->ch, array( CURLOPT_URL => '...', // 替换为你的Google API实际地址 CURLOPT_RETURNTRANSFER => true, // 安全建议:生产环境不要禁用SSL验证,保留为true,若遇证书问题可指定CA证书路径 CURLOPT_SSL_VERIFYPEER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $json, CURLOPT_HTTPHEADER => array( 'Content-Type: application/json; charset=UTF-8', // 修正为标准UTF-8写法 // 移除手动的Content-Length,让CURL自动计算,彻底避免长度错误 // 'Content-Length: ' . strlen($json), ), // 强制使用HTTP/1.1,避免部分环境下HTTP/2兼容问题导致的编码异常 CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, ));
关键修改说明
- 修正Content-Type写法:把
UTF8改成标准的UTF-8,避免严格的服务器解析失败; - 移除手动Content-Length:让CURL自动计算请求体长度,完全规避计算错误风险;
- 安全提示:
CURLOPT_SSL_VERIFYPEER => false会让请求处于不安全状态,生产环境一定要改回true; - 指定HTTP版本:强制使用HTTP/1.1,减少不同环境下的协议兼容问题。
额外验证步骤
如果还是遇到问题,可以开启CURL调试模式,查看实际发送的请求头和体:
curl_setopt($this->ch, CURLOPT_VERBOSE, true); $verbose = fopen('php://temp', 'w+'); curl_setopt($this->ch, CURLOPT_STDERR, $verbose); // 发送请求后输出调试信息 $response = curl_exec($this->ch); rewind($verbose); $verboseLog = stream_get_contents($verbose); echo "调试日志:\n" . $verboseLog;
内容的提问来源于stack exchange,提问作者Mike Robinson
相关产品推荐
相关产品推荐

