PHP CURL使用数据库存储的cookie请求返回400 Bad Request错误如何解决
核心原因
从数据库取出的cookie字符串包含肉眼不可见的隐形字符,比如换行符(\n)、回车符(\r)、首尾空格、零宽空格、UTF-8 BOM头等,echo输出时不会显示,但拼接到HTTP请求头后会破坏 header 格式,导致服务器识别失败返回:
400 Bad Request: The browser sent a request that this server could not understand
排查验证方法
- 对比变量长度确认是否存在隐形字符:
// 直接赋值的正常字符串长度 $test_cookie = 'PHPSESSID=t07gb66oduc55n982al83a7'; var_dump(strlen($test_cookie)); // 固定输出 int(41) // 数据库取出的cookie长度 var_dump(strlen($reslt->cookie));
如果两个长度不一致,即可确认存在隐形字符。
- 逐字符打印ASCII码定位异常字符:
for ($i = 0; $i < strlen($reslt->cookie); $i++) { echo $reslt->cookie[$i] . ' -> ' . ord($reslt->cookie[$i]) . '<br>'; }
如果出现ASCII码为10(\n)、13(\r)、9(\t)、32(首尾空格)、65279(UTF-8 BOM)的字符,就是问题根源。
修复方案
第一步:清洗Cookie字符串
去掉所有非法隐形字符,推荐两种清洗方式:
- 基础清洗:去除空白和控制字符
$g = trim($reslt->cookie); // 移除所有换行、回车、制表符 $g = str_replace(["\n", "\r", "\t"], '', $g);
- 严格清洗:仅保留Cookie允许的ASCII可打印字符
// 过滤掉所有非ASCII可打印字符 $g = preg_replace('/[^\x20-\x7E]/', '', $reslt->cookie); $g = trim($g);
第二步(推荐优化):使用CURL内置Cookie参数
手动拼Cookie到Header数组容易出现格式问题,更推荐用CURL原生配置项设置Cookie,兼容性更强:
$headers = array( "Accept: application/json", "Connection: keep-alive", 'Content-Type: application/json', // 移除原来手动拼接的Cookie项 ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $请求地址); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // 单独设置Cookie curl_setopt($ch, CURLOPT_COOKIE, $g); // 其余CURL配置... $response = curl_exec($ch); curl_close($ch);
额外注意
你当前的请求头数组中重复定义了Accept参数,服务器会以最后一个配置为准,如果接口需要返回JSON格式,建议删掉第二个Accept配置。
内容的提问来源于stack exchange,提问作者yagami cell
相关产品推荐
相关产品推荐

