如何用单次CURL请求在下载前检查响应头(200=正常)?
单次CURL请求同时校验响应码并下载文件
完全可以通过单次CURL请求实现需求,既能检查响应状态码是否为200,又能下载文件,彻底避免两次请求带来的内容不一致或限速问题。
基础实现方案(适合小文件)
直接发起一次请求,先校验状态码,仅当状态码为200时才将内容写入文件:
// 替换为你的实际路径和URL $downloadedFile = "目标文件路径"; $targetUrl = "要下载的URL"; $fileHandle = null; $isSuccess = false; // 初始化CURL会话 $curl = curl_init($targetUrl); // 设置CURL选项:返回响应内容、包含响应头、设置超时 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, true); curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 执行请求 $response = curl_exec($curl); if (curl_errno($curl)) { echo "cURL错误:" . curl_error($curl); } else { // 获取响应状态码 $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); if ($statusCode === 200) { // 分离响应头和正文内容 $headerLength = curl_getinfo($curl, CURLINFO_HEADER_SIZE); $fileContent = substr($response, $headerLength); // 写入文件 $fileHandle = fopen($downloadedFile, "w") or die("无法打开文件:" . $downloadedFile); fwrite($fileHandle, $fileContent); fclose($fileHandle); echo "文件下载完成"; $isSuccess = true; } else { echo "下载失败,响应码:" . $statusCode; // 状态码非200,不操作原有文件 } } // 清理CURL资源 curl_close($curl);
大文件优化方案(流式处理)
如果下载的是大文件,一次性加载全部内容会占用过多内存,可以复用CURL会话,利用HTTP持久连接实现逻辑上的“单次请求”:
// 替换为你的实际路径和URL $downloadedFile = "目标文件路径"; $targetUrl = "要下载的URL"; $fileHandle = null; $allowWrite = false; // 初始化CURL会话 $curl = curl_init($targetUrl); // 设置超时,以及自定义写入函数(控制何时写入文件) curl_setopt($curl, CURLOPT_TIMEOUT, 30); curl_setopt($curl, CURLOPT_WRITEFUNCTION, function($ch, $data) use (&$fileHandle, &$allowWrite) { // 仅当确认状态码为200时才写入文件 if ($allowWrite) { return fwrite($fileHandle, $data); } return strlen($data); // 返回数据长度,避免CURL报错 }); // 第一步:仅获取响应头,校验状态码 curl_setopt($curl, CURLOPT_NOBODY, true); curl_exec($curl); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); if ($statusCode === 200) { $allowWrite = true; // 打开文件准备写入 $fileHandle = fopen($downloadedFile, "w") or die("无法打开文件:" . $downloadedFile); // 第二步:获取响应正文并写入文件(复用同一会话,HTTP持久连接) curl_setopt($curl, CURLOPT_NOBODY, false); curl_exec($curl); fclose($fileHandle); echo "文件下载完成"; } else { echo "下载失败,响应码:" . $statusCode; } // 清理资源 curl_close($curl);
关键说明
- 基础方案通过一次请求获取全部响应,分离头和正文后按需写入,适合小文件场景。
- 大文件方案复用CURL会话,利用HTTP持久连接,实际只建立一次TCP连接,避免两次独立请求的问题,同时流式写入减少内存占用。
- 两种方案都保证了只有响应码为200时才会写入文件,不会覆盖原有文件。
内容的提问来源于stack exchange,提问作者nibb11
相关产品推荐
相关产品推荐

