0

0

FPDF 生成密码保护 PDF:前端下载解决方案

心靈之曲

心靈之曲

发布时间:2025-10-24 12:41:47

|

244人浏览过

|

来源于php中文网

原创

FPDF 生成密码保护 PDF:前端下载解决方案

本文旨在解决使用 fpdf 生成密码保护 pdf 文件时,通过 jquery ajax 调用后端导致文件无法下载,反而显示原始二进制数据的问题。文章将详细介绍如何利用 `xmlhttprequest` 的 `responsetype` 为 `blob` 来正确处理服务器返回的二进制数据,并在客户端触发文件下载,从而实现一个完整的、功能性的密码保护 pdf 下载方案。

FPDF 密码保护 PDF 的生成与下载机制

在使用 PHP 的 FPDF 库(特别是其扩展 FPDF_Protection)生成带有密码保护的 PDF 文件时,后端通常会通过设置 HTTP 响应头来指示浏览器下载文件。然而,当前端使用异步 JavaScript 请求(如 jQuery AJAX)来触发这一过程时,常常会遇到文件无法下载,反而将 PDF 的原始二进制数据作为字符串显示在页面或控制台的问题。这主要是因为传统的 AJAX 请求默认将服务器响应视为文本或 JSON 数据,而非二进制文件流。

服务端 PHP 代码:生成密码保护 PDF

首先,我们来看服务器端如何使用 FPDF_Protection 生成一个密码保护的 PDF 文件。FPDF_Protection 扩展允许我们为 PDF 设置打开密码和权限密码。

<?php
    // 确保在输出任何内容之前启动输出缓冲
    ob_start(); 

    // 引入 FPDF_Protection 库
    require('FPDF_protection.php');

    if(isset($_POST["input"]) && $_POST["input"] == "generate_pdf"){
        // 创建 FPDF_Protection 实例
        $pdf = new FPDF_Protection();

        // 设置 PDF 保护。array('print') 允许打印,$_POST["password"] 是打开密码。
        // 更多权限可以参考 FPDF_Protection 文档。
        $pdf->SetProtection(array('print'), $_POST["password"]);

        // 添加页面
        $pdf->AddPage();

        // 设置字体
        $pdf->SetFont('Arial');

        // 写入内容
        $pdf->Write(10,"Hello, this is a password-protected PDF.");

        // 输出 PDF 到浏览器进行下载
        // 'D' 参数表示“下载”,"Recovery_code.pdf" 是下载时的文件名
        $pdf->Output('D',"Recovery_code.pdf");

        // 刷新输出缓冲区,确保所有内容都被发送
        ob_end_flush(); 
    }
?>

代码解析与注意事项:

  1. ob_start() 和 ob_end_flush(): 这两个函数至关重要。ob_start() 启动输出缓冲,FPDF 在生成 PDF 时会直接向输出缓冲区写入数据和 HTTP 头。如果没有缓冲,任何意外的空白字符或错误信息都可能在 PDF 数据之前发送,导致 PDF 文件损坏或下载失败。ob_end_flush() 则确保缓冲区中的所有内容(包括 PDF 数据和下载头)都被发送到客户端。
  2. require('FPDF_protection.php'): 确保你已经正确引入了 FPDF_Protection 库文件。
  3. $pdf->SetProtection(array('print'), $_POST["password"]): 这是设置 PDF 保护的核心。第一个参数是一个数组,定义了允许的操作(如 'print', 'copy', 'modify' 等)。第二个参数是用户打开 PDF 时需要输入的密码。
  4. $pdf->Output('D', "Recovery_code.pdf"): Output() 方法的第一个参数 'D' 指示浏览器将文件作为附件下载。第二个参数是建议的文件名。

前端 JavaScript 代码:处理二进制下载

当服务器返回的是一个二进制文件流时,传统的 jQuery.ajax 方法的 success 回调会尝试将响应体解析为字符串,这正是导致乱码或原始二进制数据显示的原因。为了正确处理这种情况,我们需要使用 XMLHttpRequest 并指定 responseType 为 blob。

PaperFake
PaperFake

AI写论文

下载

立即学习前端免费学习笔记(深入)”;

<script>
document.getElementById("downloadButton").addEventListener("click", function() {
    var req = new XMLHttpRequest();
    var password = document.getElementById("password").value;
    var params = "input=generate_pdf&password=" + encodeURIComponent(password); // 对密码进行编码

    req.open("POST", "backend.php", true); // 使用 POST 方法请求后端
    req.responseType = "blob"; // 关键:指定响应类型为 blob,用于处理二进制数据
    req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); // 设置请求头

    req.onreadystatechange = function () {
        // 当请求状态为 DONE (4) 且 HTTP 状态码为 OK (200) 时
        if (req.readyState === 4 && req.status === 200) {
            // 创建一个 Blob 对象,其中包含服务器返回的二进制数据
            var blob = new Blob([req.response], { type: 'application/pdf' }); // 指定 MIME 类型

            // 创建一个临时的 URL,指向这个 Blob 对象
            var link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);

            // 设置下载的文件名
            link.download = "Recovery_code.pdf"; // 建议与后端 Output 方法中的文件名一致

            // 模拟点击下载链接
            document.body.appendChild(link); // 某些浏览器需要将链接添加到 DOM 才能点击
            link.click();

            // 释放 URL 对象,防止内存泄漏
            window.URL.revokeObjectURL(link.href);
            document.body.removeChild(link); // 清理 DOM
        } else if (req.readyState === 4 && req.status !== 200) {
            // 处理错误情况,例如服务器返回非200状态码
            console.error("PDF 下载失败,HTTP 状态码: " + req.status);
            alert("PDF 下载失败,请稍后再试。");
        }
    };
    req.send(params); // 发送请求
});
</script>

<!-- HTML 示例,用于触发下载 -->
<div>
    <label for="password">PDF 密码:</label>
    <input type="password" id="password" value="mysecretpassword">
    <button id="downloadButton">下载密码保护 PDF</button>
</div>

代码解析与注意事项:

  1. req.responseType = "blob": 这是解决问题的核心。它告诉 XMLHttpRequest 将服务器响应作为 Blob 对象处理,而不是尝试解析为文本。
  2. var params = "input=generate_pdf&password=" + encodeURIComponent(password);: 构建 POST 请求体参数。encodeURIComponent 用于对密码等特殊字符进行编码,确保数据传输的正确性。
  3. req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');: 对于 POST 请求,设置正确的 Content-type 头是必要的,以便服务器正确解析请求体。
  4. var blob = new Blob([req.response], { type: 'application/pdf' });: 当请求成功时,req.response 将是一个 Blob 对象。我们将其封装在一个新的 Blob 中,并明确指定其 MIME 类型为 'application/pdf',这有助于浏览器正确识别文件类型。
  5. window.URL.createObjectURL(blob): 这是一个非常方便的 API,它会为 Blob 对象创建一个临时的 URL。这个 URL 可以像普通的文件 URL 一样被浏览器处理。
  6. link.download = "Recovery_code.pdf": 设置 <a> 标签的 download 属性,可以强制浏览器下载文件,并指定下载时的文件名。
  7. link.click(): 通过 JavaScript 模拟点击这个隐藏的下载链接,从而触发文件下载。
  8. window.URL.revokeObjectURL(link.href): 在文件下载触发后,应该及时释放由 createObjectURL 创建的临时 URL,以避免内存泄漏。
  9. 错误处理: 增加了 else if (req.readyState === 4 && req.status !== 200) 分支,用于处理服务器返回非 200 状态码时的错误情况,提升用户体验。

总结

通过结合 PHP 后端的 FPDF_Protection 库和前端 XMLHttpRequest 的 responseType = "blob" 特性,我们可以优雅地实现密码保护 PDF 文件的生成与下载功能。关键在于理解二进制数据在 HTTP 请求和响应中的处理方式,并选择正确的客户端 API 来处理文件流。这种方法不仅适用于 PDF 文件,也适用于任何需要从服务器下载二进制文件的场景。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

457

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

549

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

337

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

jquery插件有哪些
jquery插件有哪些

jquery插件有jQuery UI、jQuery Validate、jQuery DataTables、jQuery Slick、jQuery LazyLoad、jQuery Countdown、jQuery Lightbox、jQuery FullCalendar、jQuery Chosen和jQuery EasyUI等。本专题为大家提供jquery插件相关的文章、下载、课程内容,供大家免费下载体验。

156

2023.09.12

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

337

2023.10.13

jquery删除元素的方法
jquery删除元素的方法

jquery可以通过.remove() 方法、 .detach() 方法、.empty() 方法、.unwrap() 方法、.replaceWith() 方法、.html('') 方法和.hide() 方法来删除元素。更多关于jquery相关的问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

406

2023.11.10

jQuery hover()方法的使用
jQuery hover()方法的使用

hover()是jQuery中一个常用的方法,它用于绑定两个事件处理函数,这两个函数将在鼠标指针进入和离开匹配的元素时执行。想了解更多hover()的相关内容,可以阅读本专题下面的文章。

515

2023.12.04

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 13.5万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号