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

基于PHP/AJAX从URL批量下载图片的问题与实现需求

问题解决:修复图片损坏+AJAX分批下载

一、修复服务器端图片下载损坏问题

你的curl代码缺少HTTPS验证处理、请求头模拟,且未捕获错误,这是导致图片损坏的核心原因。以下是修复后的代码:

<?php
$images = [
    'http://ensemblepakistan.com/wp-content/uploads/2018/06/11.jpg',
    'https://ensemblepakistan.com/wp-content/uploads/2018/08/SHK-242-3.jpg',
    'https://ensemblepakistan.com/wp-content/uploads/2018/08/SHK-242-1.jpg',
    'https://ensemblepakistan.com/wp-content/uploads/2018/08/SHK-242-2.jpg',
    'https://ensemblepakistan.com/wp-content/uploads/2018/08/SHBK-258-3.jpg',
    'https://ensemblepakistan.com/wp-content/uploads/2018/08/SHBK-258-2.jpg',
    'https://ensemblepakistan.com/wp-content/uploads/2018/08/SHBK-258-1.jpg',
    'https://ensemblepakistan.com/wp-content/uploads/2018/10/SHBK-313-3-min.jpg'
];

$saveDir = $_SERVER['DOCUMENT_ROOT'] . '/test/';
// 确保保存目录存在
if (!is_dir($saveDir)) {
    mkdir($saveDir, 0755, true);
}

foreach ($images as $image) {
    $name = basename($image);
    // 处理重名文件,避免覆盖
    $savePath = $saveDir . $name;
    $counter = 1;
    while (file_exists($savePath)) {
        $ext = pathinfo($name, PATHINFO_EXTENSION);
        $baseName = pathinfo($name, PATHINFO_FILENAME);
        $savePath = $saveDir . "{$baseName}_{$counter}.{$ext}";
        $counter++;
    }

    $ch = curl_init($image);
    $fp = fopen($savePath, 'wb');
    
    curl_setopt_array($ch, [
        CURLOPT_FILE => $fp,
        CURLOPT_HEADER => false,
        CURLOPT_FOLLOWLOCATION => true, // 跟随重定向
        CURLOPT_SSL_VERIFYPEER => false, // 跳过SSL证书验证(按需开启)
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', // 模拟浏览器请求
        CURLOPT_TIMEOUT => 30 // 设置超时时间
    ]);

    $result = curl_exec($ch);
    if (!$result) {
        // 捕获curl错误
        error_log("下载失败:{$image},错误信息:" . curl_error($ch));
        fclose($fp);
        unlink($savePath); // 删除空文件
        curl_close($ch);
        continue;
    }

    // 检查HTTP响应码是否为200
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    if ($httpCode !== 200) {
        error_log("下载失败:{$image},HTTP状态码:{$httpCode}");
        fclose($fp);
        unlink($savePath);
        curl_close($ch);
        continue;
    }

    curl_close($ch);
    fclose($fp);
}

关键修复点:

  • 添加CURLOPT_FOLLOWLOCATION处理重定向,部分图片URL可能存在跳转
  • 跳过SSL证书验证(针对HTTPS站点,若服务器信任证书可移除)
  • 模拟浏览器User-Agent,避免被目标服务器拦截
  • 处理重名文件,防止覆盖已有图片
  • 捕获curl错误和HTTP状态码,及时清理损坏文件

二、实现AJAX分批下载

需要前端JS和后端接口配合,每次请求下载指定数量的图片,完成后自动发起下一批请求。

1. 后端接口(batch-download.php)

<?php
$images = [
    // 你的图片URL数组
    'http://ensemblepakistan.com/wp-content/uploads/2018/06/11.jpg',
    'https://ensemblepakistan.com/wp-content/uploads/2018/08/SHK-242-3.jpg',
    // ... 其他图片URL
];

$start = isset($_POST['start']) ? (int)$_POST['start'] : 0;
$limit = isset($_POST['limit']) ? (int)$_POST['limit'] : 20;

$batchImages = array_slice($images, $start, $limit);
$successCount = 0;
$errorUrls = [];

$saveDir = $_SERVER['DOCUMENT_ROOT'] . '/test/';
if (!is_dir($saveDir)) {
    mkdir($saveDir, 0755, true);
}

foreach ($batchImages as $image) {
    $name = basename($image);
    $savePath = $saveDir . $name;
    $counter = 1;
    while (file_exists($savePath)) {
        $ext = pathinfo($name, PATHINFO_EXTENSION);
        $baseName = pathinfo($name, PATHINFO_FILENAME);
        $savePath = $saveDir . "{$baseName}_{$counter}.{$ext}";
        $counter++;
    }

    $ch = curl_init($image);
    $fp = fopen($savePath, 'wb');
    
    curl_setopt_array($ch, [
        CURLOPT_FILE => $fp,
        CURLOPT_HEADER => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
        CURLOPT_TIMEOUT => 30
    ]);

    $result = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
    curl_close($ch);
    fclose($fp);

    if ($result && $httpCode === 200) {
        $successCount++;
    } else {
        $errorUrls[] = $image;
        unlink($savePath);
    }
}

echo json_encode([
    'success' => true,
    'successCount' => $successCount,
    'errorUrls' => $errorUrls,
    'totalImages' => count($images),
    'currentStart' => $start,
    'limit' => $limit
]);

2. 前端AJAX代码(HTML页面)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>分批图片下载</title>
</head>
<body>
    <div id="progress"></div>
    <script>
        const batchSize = 20; // 每次下载20张
        let currentStart = 0;
        const totalImages = 8; // 替换为实际图片总数

        function downloadBatch() {
            if (currentStart >= totalImages) {
                document.getElementById('progress').textContent = '所有图片下载完成!';
                return;
            }

            fetch('batch-download.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: `start=${currentStart}&limit=${batchSize}`
            })
            .then(response => response.json())
            .then(data => {
                const progressText = `已完成 ${Math.min(currentStart + batchSize, totalImages)}/${totalImages} 张图片,成功下载 ${data.successCount} 张,失败 ${data.errorUrls.length} 张`;
                document.getElementById('progress').textContent = progressText;

                currentStart += batchSize;
                // 延迟1秒发起下一批请求(避免服务器压力过大)
                setTimeout(downloadBatch, 1000);
            })
            .catch(error => {
                document.getElementById('progress').textContent = `请求失败:${error.message}`;
            });
        }

        // 启动下载
        downloadBatch();
    </script>
</body>
</html>

分批下载逻辑说明:

  • 前端维护currentStart变量,标记当前批次的起始索引
  • 每次请求后端接口,传入start和limit参数,后端截取对应批次的图片数组进行下载
  • 后端返回下载结果后,前端更新进度,并自动发起下一批请求,直到所有图片处理完成
  • 添加延迟请求,避免短时间内大量请求导致服务器负载过高

内容的提问来源于stack exchange,提问作者Sahibzada Jawad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 20:55:50