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

PHP调用ILovePDF REST API压缩PDF自动下载的问题排查与解决

问题解决:PHP调用ILovePDF API压缩PDF后直接浏览器下载

问题总结

当前代码存在三个核心问题:

  • 压缩后下载的文件名与原上传文件名不一致
  • 下载的PDF文件损坏无法打开
  • 控制台报错:Uncaught (in promise) Error: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received

需求目标:压缩后的PDF以原文件名直接下载到用户浏览器,不保存到服务器(或下载后自动删除临时文件)

错误原因分析

  1. 错误调用$myTask->download():该方法默认会将压缩文件保存到服务器本地,而非直接输出到浏览器,后续的header设置完全无效(因为已经有文件内容输出)
  2. filesize($file)参数错误:$file是ILovePDF SDK返回的文件对象,不是本地文件路径,无法获取正确文件大小
  3. 未处理临时文件:上传的原文件和压缩后的文件都留在服务器,不符合需求
  4. 输出顺序错误:header必须在任何内容输出前发送,原代码先执行下载保存,再设置header,导致header无法生效

修正后的代码

<?php
require_once('../vendor/autoload.php');
use Ilovepdf\CompressTask;

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    if (isset($_FILES["pdf_file"]) && $_FILES["pdf_file"]["error"] === 0) {
        $tempFileName = $_FILES["pdf_file"]["tmp_name"];
        $originalFileName = $_FILES["pdf_file"]["name"];
        
        // 确保文件名是安全的PDF格式
        $safeFileName = preg_replace('/[^a-zA-Z0-9_\-\.]/', '', $originalFileName);
        if (!str_ends_with(strtolower($safeFileName), '.pdf')) {
            $safeFileName .= '.pdf';
        }

        $myTask = new CompressTask('public_key', 'secret_key');
        // 直接使用上传的临时文件,无需移动到服务器目录
        $file = $myTask->addFile($tempFileName, $originalFileName);
        
        try {
            $myTask->execute();
            
            // 获取压缩后的文件内容(不保存到服务器)
            $compressedContent = $myTask->download('string');
            
            // 发送下载header
            header("Content-Type: application/pdf");
            header("Content-Disposition: attachment; filename=\"{$safeFileName}\"");
            header("Content-Length: " . strlen($compressedContent));
            header("Cache-Control: no-cache");
            header("Pragma: no-cache");
            
            // 输出文件内容到浏览器
            echo $compressedContent;
            exit;
        } catch (Exception $e) {
            echo "压缩失败:" . $e->getMessage();
        }
    } else {
        echo "文件上传错误:" . $_FILES["pdf_file"]["error"];
    }
}
?>

关键改动说明

  • 移除move_uploaded_file:直接使用PHP上传的临时文件,避免在服务器留存原文件
  • 使用$myTask->download('string'):获取压缩后的文件内容字符串,而非保存到本地
  • 提前设置header:确保在输出文件内容前发送所有响应头,避免文件损坏
  • 安全处理文件名:过滤非法字符,确保文件名符合HTTP规范,避免下载时出现文件名异常
  • 添加异常捕获:处理API调用过程中可能出现的错误(如密钥无效、文件格式错误等)
  • 输出内容后立即exit:防止后续输出多余内容导致文件损坏

可选方案(需临时保存文件的场景)

如果需要临时保存压缩文件(比如记录日志),可以在下载后删除:

// 替换上述代码中的download和输出部分
$tempCompressedPath = sys_get_temp_dir() . '/' . uniqid() . '.pdf';
$myTask->download($tempCompressedPath);

// 发送header
header("Content-Type: application/pdf");
header("Content-Disposition: attachment; filename=\"{$safeFileName}\"");
header("Content-Length: " . filesize($tempCompressedPath));
header("Cache-Control: no-cache");
header("Pragma: no-cache");

// 输出文件内容
readfile($tempCompressedPath);
// 删除临时文件
unlink($tempCompressedPath);
exit;

内容的提问来源于stack exchange,提问作者Hüseyin Hamo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:02:03