如何在Django中展示PDF并禁止下载、打印操作
站点内PDF查看限制:禁止下载与打印的实现方案
针对你遇到的问题,以下是几个能有效提高门槛的实现思路,都是适合新手上手的方案:
1. 用PDF.js做纯前端渲染(推荐)
这是Mozilla开源的PDF渲染库,完全靠HTML5在浏览器里渲染PDF内容,不依赖浏览器自带的PDF阅读器,从根源上避免用户用原生控件下载/打印。
- 核心操作:
- 隐藏默认工具栏:初始化时关闭下载、打印按钮,同时可禁用文本选择增强防护。
- 后端配合:不要直接暴露PDF文件的URL,而是通过接口返回文件流,且接口必须做用户权限校验,只有登录用户才能获取。
- 简单代码示例:
// 引入PDF.js库后初始化 const pdfUrl = '/api/secure-get-pdf?bookId=xxx'; // 后端权限接口 pdfjsLib.getDocument(pdfUrl).promise.then(pdf => { // 逐页渲染到页面容器 for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) { pdf.getPage(pageNum).then(page => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const viewport = page.getViewport({ scale: 1.2 }); canvas.width = viewport.width; canvas.height = viewport.height; // 渲染PDF页面 page.render({ canvasContext: ctx, viewport }); // 可选:添加水印防截图传播 const watermarkCtx = canvas.getContext('2d'); watermarkCtx.fillStyle = 'rgba(0,0,0,0.2)'; watermarkCtx.font = '24px sans-serif'; watermarkCtx.fillText('仅本站查看 - 用户ID:123', 50, canvas.height/2); // 将渲染后的canvas添加到页面 document.getElementById('pdf-wrap').appendChild(canvas); }); } }); - 额外防护:给渲染区域禁用右键菜单:
document.getElementById('pdf-wrap').oncontextmenu = () => false;
2. 后端流+iframe限制(快速实现)
如果不想折腾前端渲染,可以用iframe嵌入,但必须配合后端做权限和响应头控制:
- 后端处理:
写一个接口,校验用户身份后返回PDF文件流,同时设置响应头:
前者强制浏览器在页面内打开,后者禁止浏览器缓存PDF文件。Content-Disposition: inline; filename="book.pdf" Cache-Control: no-store - 前端iframe配置:
<iframe src="/api/get-authorized-pdf?bookId=xxx" width="100%" height="800px" sandbox="allow-same-origin" oncontextmenu="return false;" ></iframe>sandbox属性限制iframe的权限,防止用户通过iframe的API操作PDF。
3. 禁止打印的补充手段
- 用CSS屏蔽打印:
@media print { body, .pdf-wrap, iframe { visibility: hidden !important; } } - 监听打印事件阻止默认行为:
window.addEventListener('beforeprint', (e) => { e.preventDefault(); alert('本内容禁止打印'); });
重要提醒
没有绝对完美的防护方案,技术上无法完全阻止有经验的用户(比如抓包、截图),但以上方案能挡住绝大多数普通用户,同时满足站点内查看的需求。核心是永远不要把PDF文件放在公开目录,所有访问都必须经过后端权限校验。
内容的提问来源于stack exchange,提问作者Максим Макаров
相关产品推荐
相关产品推荐

