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

使用Ajax结合CodeIgniter触发PDF下载失败问题求助

我来帮你解决这个问题!你遇到的核心问题是Ajax请求无法触发浏览器的文件下载行为——因为Ajax的响应会被JavaScript接管,而不是交给浏览器去处理下载流程。直接访问URL时,浏览器会自动解析响应头里的Content-Disposition字段,弹出下载窗口,但Ajax做不到这一点。

解决方案1:替换Ajax为直接跳转/模拟点击(最简单有效)

放弃使用Ajax,直接让浏览器发起普通的HTTP请求,这样就能触发下载流程。修改你的前端函数:

function DownLoadPdf(id) {
    // 直接跳转到下载接口,浏览器会自动处理下载
    window.location.href = "<?php echo base_url();?>admin/packages/downloadpdf/"+id;
    
    // 如果你需要更灵活的方式(比如指定文件名),可以用临时a标签模拟点击:
    // const tempLink = document.createElement('a');
    // tempLink.href = "<?php echo base_url();?>admin/packages/downloadpdf/"+id;
    // tempLink.setAttribute('download', 'package_'+id+'.pdf'); // 可选,自定义文件名
    // document.body.appendChild(tempLink);
    // tempLink.click();
    // document.body.removeChild(tempLink);
}

解决方案2:优化你的CodeIgniter控制器代码

另外,你当前的控制器代码存在两个小问题:一是会把PDF文件下载到服务器本地(长期运行会占用磁盘空间),二是最后的echo "success"会破坏PDF文件的完整性。可以优化成直接输出远程文件内容,无需保存到服务器:

function downloadpdf($pid) {
    set_time_limit(0);
    $url = "http://www.malayatourism.com/uploads/images/packages/pdf/$pid.pdf";
    
    // 直接获取远程PDF内容,不保存到服务器
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 处理可能的重定向
    $fileContent = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    // 检查是否成功获取文件
    if ($httpCode !== 200 || empty($fileContent)) {
        show_error('无法获取指定的PDF文件', 404);
        return;
    }
    
    $fileName = basename($url);
    // 设置正确的响应头
    header('Content-Description: File Transfer');
    header('Content-Type: application/pdf'); // 用更准确的PDF MIME类型
    header('Content-Disposition: attachment; filename="'.$fileName.'"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . strlen($fileContent));
    
    ob_clean();
    flush();
    echo $fileContent;
    exit; // 必须exit,避免输出多余内容破坏PDF
}

额外说明

  • 你原来的Ajax代码里传了pid参数,但控制器是通过URL路由的$pid获取的,所以POST的data其实没用,可以直接去掉。
  • 优化后的控制器不再生成服务器本地文件,既节省空间又避免了权限问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:03:44