PHP CURL自定义Header与实际请求不一致问题求助
PHP cURL自定义HTTP Header重复问题
问题详情
我编写的PHP cURL POST请求代码,发送的HTTP Header和自定义的不一致,每个自定义Header都出现了重复项——一个是空值的默认项,一个是我设置的自定义值。
我的代码
<?php function post($url, $data, $header) { $ch = curl_init(); if(substr($url, 0, 5) == 'https') { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $response = curl_exec($ch); if($error = curl_error($ch)){ die($error); } curl_close($ch); return $response; } $pdfHeader = [ 'Content-Type:application/json;charset=UTF-8', 'Connection:keep-alive', 'userId:1a2b3c4d5e6f', 'token:abcdefg' ]; $pdfURL = 'http://www.example.com/api'; $pdfParam = 'pdfName=test.pdf&page=1'; echo post($pdfURL, $pdfParam, $pdfHeader); ?>
预期Header
Content-Type:application/json; charset=UTF-8; Connection:keep-alive; userId=1a2b3c4d5e6f; token:abcdefg
实际发送的Header
Content-Type: Content-Type:application/json; charset=UTF-8; Connection: Connection:keep-alive; userId: userId:a1b2c3d4e5f6; token: token:abcdefg
用其他语言实现相同功能时没有这个问题。
问题原因
- Header格式不规范:自定义Header的写法是
键:值(冒号后无空格),不符合HTTP Header的标准格式,导致cURL无法正确识别为合法的键值对,默认Header没有被覆盖,反而同时发送了默认空值项和自定义项。 - POST数据与Content-Type不匹配:设置的
Content-Type是application/json,但POST数据是x-www-form-urlencoded格式,这种不匹配会干扰cURL对Header的处理逻辑。 - cURL默认Header未被覆盖:cURL会自动添加
Content-Type、Connection等默认Header,当自定义Header格式错误时,无法替换这些默认项,造成重复。
解决方案
1. 修正Header格式
每个Header项必须是键: 值的格式(冒号后加空格),这是HTTP Header的标准写法,cURL才能正确识别并覆盖默认项:
$pdfHeader = [ 'Content-Type: application/json; charset=UTF-8', 'Connection: keep-alive', 'userId: 1a2b3c4d5e6f', 'token: abcdefg' ];
2. 匹配POST数据与Content-Type
既然设置了application/json的Content-Type,POST数据需要转为JSON字符串:
$pdfParam = json_encode([ 'pdfName' => 'test.pdf', 'page' => 1 ]);
如果接口实际接受x-www-form-urlencoded格式,就把Header里的Content-Type改成'Content-Type: application/x-www-form-urlencoded',保持原POST数据格式即可。
3. 可选:禁用多余默认Header
如果重复问题依然存在,可以强制移除cURL自动添加的Expect等Header,避免干扰:
// 在设置CURLOPT_HTTPHEADER后添加 curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($header, ['Expect:']));
修改后的完整代码
<?php function post($url, $data, $header) { $ch = curl_init(); if(substr($url, 0, 5) == 'https') { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 显式设置为2,更安全规范 } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // 可选:移除默认的Expect Header curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($header, ['Expect:'])); $response = curl_exec($ch); if($error = curl_error($ch)){ die($error); } curl_close($ch); return $response; } $pdfHeader = [ 'Content-Type: application/json; charset=UTF-8', 'Connection: keep-alive', 'userId: 1a2b3c4d5e6f', 'token: abcdefg' ]; $pdfURL = 'http://www.example.com/api'; $pdfParam = json_encode([ 'pdfName' => 'test.pdf', 'page' => 1 ]); echo post($pdfURL, $pdfParam, $pdfHeader); ?>
内容的提问来源于stack exchange,提问作者Vindows 95
相关产品推荐
相关产品推荐

