You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

用其他语言实现相同功能时没有这个问题。


问题原因

  1. Header格式不规范:自定义Header的写法是键:值(冒号后无空格),不符合HTTP Header的标准格式,导致cURL无法正确识别为合法的键值对,默认Header没有被覆盖,反而同时发送了默认空值项和自定义项。
  2. POST数据与Content-Type不匹配:设置的Content-Type是application/json,但POST数据是x-www-form-urlencoded格式,这种不匹配会干扰cURL对Header的处理逻辑。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:32:58