·设为首页收藏本站📧邮箱修改🎁免费下载专区📒收藏夹👽聊天室📱AI智能体
返回列表 发布新帖

pdf.js屏蔽复制、打印、下载功能并加水印

753 3
发表于 2022-10-29 12:18:55 | 查看全部 阅读模式

马上注册,免费下载更多dz插件网资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
屏蔽功能按钮
新版 pdf.js 使用style设置隐藏无效,经研究可以通过 setAttribute 较好的解决。
viewer.html 的<head>最后,添加:
  1. <script>function onBodyLoad(){    var appConfig = PDFViewerApplication.appConfig;    appConfig.toolbar.viewBookmark.setAttribute('hidden', 'true');   appConfig.secondaryToolbar.viewBookmarkButton.setAttribute('hidden', 'true');    appConfig.toolbar.openFile.setAttribute('hidden', 'true');    appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true');    appConfig.toolbar.download.setAttribute('hidden', 'true');    appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true');    appConfig.toolbar.print.setAttribute('hidden', 'true');    appConfig.secondaryToolbar.printButton.setAttribute('hidden', 'true');}</script>
复制代码
<body> 添加下列属性:onload="onBodyLoad()"
这样,打开、打印、下载按钮就消失了



解决了下载按钮之后,我发现鼠标焦点在iframe里时 使用ctrl+s也能下载文件。解决这个问题同样也是找到pdf/web/viewer.js,注释下载代码就ok了。(不同版本所在行数可能不同,根据行数找不到时请根据内容搜索)
pdf.js屏蔽复制、打印、下载功能并加水印 pdf,屏蔽,复制,打印,下载



这样用户就无法下载pdf文件了,我们的目的就达到了


禁用鼠标选择、鼠标右键等操作,修改viewer.jsp的body标签,添加属性改为如下内容:
  1. <body tabindex="1" class="loadingInProgress"        tabindex="1" class="loadingInProgress"        oncontextmenu="return false;" leftMargin="0" topMargin="0"        oncopy="return false;" oncut="return false;"        onselectstart="return false">
复制代码
添加全局水印
利用canvas添加全局水印,其实就是在viewer.js中遍历文件元素节点的同时,创建水印元素节点并插入到每一页的位置。原文参考


1.在viewer.js中找到如下内容,位置大概在11973行前后:
  1. if (this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && this.textLayerFactory) {   var textLayerDiv = document.createElement('div');   textLayerDiv.className = 'textLayer';   textLayerDiv.style.width = canvasWrapper.style.width;   textLayerDiv.style.height = canvasWrapper.style.height;   //---这里就是要插入水印的位置---   if (this.annotationLayer && this.annotationLayer.div) {      div.insertBefore(textLayerDiv, this.annotationLayer.div);   } else {      div.appendChild(textLayerDiv);   }   textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.textLayerMode === _ui_utils.TextLayerMode.ENABLE_ENHANCE);}
复制代码
  1. if (this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && this.textLayerFactory) {    var textLayerDiv = document.createElement('div');    textLayerDiv.className = 'textLayer';    textLayerDiv.style.width = canvasWrapper.style.width;    textLayerDiv.style.height = canvasWrapper.style.height;    //---------------------水印开始---------------------    var cover = document.createElement('div');    cover.className = "cover";    cover.innerText = "内容保密,请勿复制或下载"; //这里就是水印内容,如果要按照不同的文件显示不同的水印,可参考pdf文件路径的传值方式,在viewer.jsp中head部位接收后台传值并在这里使用    if (this.annotationLayer) {        // annotationLayer needs to stay on top        div.insertBefore(textLayerDiv, this.annotationLayer.div);        div.appendChild(cover);    } else {        div.appendChild(textLayerDiv);        div.appendChild(cover);    }    var coverEle = document.getElementsByClassName('cover'),size = 0,        nowWidth = +canvasWrapper.style.width.split("p")[0],        //714为100%时,每页的宽度。对比当前的宽度可以计算出页面变化后字体的数值        size = 50 * nowWidth / 714 + "px";    for(var i=0, len=coverEle.length; i<len; i++){        coverEle[i].style.fontSize = size;        coverEle[i].style.width = canvasWrapper.style.width;        coverEle[i].style.height = canvasWrapper.style.height / 10;    }    //---------------------水印结束---------------------    if (this.annotationLayer && this.annotationLayer.div) {        div.insertBefore(textLayerDiv, this.annotationLayer.div);    } else {        div.appendChild(textLayerDiv);    }    textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.textLayerMode === _ui_utils.TextLayerMode.ENABLE_ENHANCE);}
复制代码
3.最后在viewer.css文件开始位置添加水印的css样式完成水印显示:
  1. /* 水印遮罩层 */.cover{  z-index: 100;  position: absolute;  top: 41%;  left: 1%;  transform: rotate(330deg);  text-align: center;  font-size: 310%;  padding-left: 30px;  letter-spacing: 18px;  color:rgba(162, 162, 162, 0.4);}
复制代码
我要说一句 收起回复

评论3

Discuz智能体Lv.8 发表于 2025-3-16 12:15:36 | 查看全部
要实现PDF.js的复制、打印、下载功能的屏蔽,并添加水印,可以按照以下步骤进行操作:

### 1. 屏蔽功能按钮
在`viewer.html`文件的最后添加以下代码:

  1. function onBodyLoad() {
  2.     var appConfig = PDFViewerApplication.appConfig;
  3.     appConfig.toolbar.viewBookmark.setAttribute('hidden', 'true');
  4.     appConfig.secondaryToolbar.viewBookmarkButton.setAttribute('hidden', 'true');
  5.     appConfig.toolbar.openFile.setAttribute('hidden', 'true');
  6.     appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true');
  7.     appConfig.toolbar.download.setAttribute('hidden', 'true');
  8.     appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true');
  9.     appConfig.toolbar.print.setAttribute('hidden', 'true');
  10.     appConfig.secondaryToolbar.printButton.setAttribute('hidden', 'true');
  11. }
复制代码


然后在`<body>`标签中添加`onload="onBodyLoad()"`属性:

  1. <body onload="onBodyLoad()">
复制代码


### 2. 禁用快捷键下载
为了防止用户通过快捷键(如`Ctrl+S`)下载PDF文件,可以在`viewer.js`中找到并注释掉相关的下载代码。具体位置可能因版本不同而有所差异,可以通过搜索`download`关键字找到相关代码并注释掉。

### 3. 禁用鼠标选择和右键菜单
在`viewer.jsp`文件的`<body>`标签中添加以下属性:

  1. <body oncontextmenu="return false;" onselectstart="return false;">
复制代码


### 4. 添加全局水印
在`viewer.js`中找到以下代码段(大约在11973行前后):

  1. if (this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && this.textLayerFactory) {
  2.     var textLayerDiv = document.createElement('div');
  3.     textLayerDiv.className = 'textLayer';
  4.     textLayerDiv.style.width = canvasWrapper.style.width;
  5.     textLayerDiv.style.height = canvasWrapper.style.height;
  6.     //---这里就是要插入水印的位置---
  7.     if (this.annotationLayer && this.annotationLayer.div) {
  8.         div.insertBefore(textLayerDiv, this.annotationLayer.div);
  9.     } else {
  10.         div.appendChild(textLayerDiv);
  11.     }
  12.     textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.textLayerMode === _ui_utils.TextLayerMode.ENABLE_ENHANCE);
  13. }
复制代码


在该位置插入水印代码:

  1. if (this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && this.textLayerFactory) {
  2.     var textLayerDiv = document.createElement('div');
  3.     textLayerDiv.className = 'textLayer';
  4.     textLayerDiv.style.width = canvasWrapper.style.width;
  5.     textLayerDiv.style.height = canvasWrapper.style.height;
  6.     //---------------------水印开始---------------------
  7.     var cover = document.createElement('div');
  8.     cover.className = "cover";
  9.     cover.innerText = "内容保密,请勿复制或下载"; //这里就是水印内容,如果要按照不同的文件显示不同的水印,可参考pdf文件路径的传值方式,在viewer.jsp中head部位接收后台传值并在这里使用
  10.     if (this.annotationLayer) {
  11.         // annotationLayer needs to stay on top
  12.         div.insertBefore(textLayerDiv, this.annotationLayer.div);
  13.         div.appendChild(cover);
  14.     } else {
  15.         div.appendChild(textLayerDiv);
  16.         div.appendChild(cover);
  17.     }
  18.     var coverEle = document.getElementsByClassName('cover'), size = 0,
  19.         nowWidth = +canvasWrapper.style.width.split("p"),
  20.         //714为100%时,每页的宽度。对比当前的宽度可以计算出页面变化后字体的数值
  21.         size = 50 * nowWidth / 714 + "px";
  22.     for (var i = 0, len = coverEle.length; i < len; i++) {
  23.         coverEle[i].style.fontSize = size;
  24.     }
  25.     //---------------------水印结束---------------------
  26.     textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.textLayerMode === _ui_utils.TextLayerMode.ENABLE_ENHANCE);
  27. }
复制代码


### 5. 样式调整
在`viewer.css`中添加以下样式以调整水印的显示效果:

  1. .cover {
  2.     position: absolute;
  3.     top: 0;
  4.     left: 0;
  5.     width: 100%;
  6.     height: 100%;
  7.     display: flex;
  8.     justify-content: center;
  9.     align-items: center;
  10.     color: rgba(0, 0, 0, 0.5);
  11.     font-size: 50px;
  12.     pointer-events: none;
  13.     z-index: 1000;
  14. }
复制代码


通过以上步骤,你可以实现PDF.js的复制、打印、下载功能的屏蔽,并添加全局水印。如果有任何问题或需要进一步的帮助,请随时联系我。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复
Discuz智能体Lv.8 发表于 2025-3-19 16:55:55 | 查看全部
要实现PDF.js的屏蔽复制、打印、下载功能并添加水印,您可以按照以下步骤进行操作:

### 1. 屏蔽功能按钮
在`viewer.html`文件的最后添加以下代码:

  1. function onBodyLoad() {
  2.     var appConfig = PDFViewerApplication.appConfig;
  3.     appConfig.toolbar.viewBookmark.setAttribute('hidden', 'true');
  4.     appConfig.secondaryToolbar.viewBookmarkButton.setAttribute('hidden', 'true');
  5.     appConfig.toolbar.openFile.setAttribute('hidden', 'true');
  6.     appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true');
  7.     appConfig.toolbar.download.setAttribute('hidden', 'true');
  8.     appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true');
  9.     appConfig.toolbar.print.setAttribute('hidden', 'true');
  10.     appConfig.secondaryToolbar.printButton.setAttribute('hidden', 'true');
  11. }
复制代码


然后在`<body>`标签中添加`onload="onBodyLoad()"`属性:

  1. <body onload="onBodyLoad()">
复制代码


### 2. 禁用快捷键下载
为了防止用户通过快捷键(如`Ctrl+S`)下载PDF文件,您需要修改`viewer.js`文件。找到与下载相关的代码并注释掉。具体位置可能因版本不同而有所差异,您可以通过搜索`download`关键字来定位相关代码。

### 3. 禁用鼠标选择和右键菜单
在`viewer.html`的`<body>`标签中添加以下属性:

  1. <body onload="onBodyLoad()" oncontextmenu="return false;" onselectstart="return false;">
复制代码


### 4. 添加全局水印
在`viewer.js`文件中找到以下代码段(大约在11973行前后):

  1. if (this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && this.textLayerFactory) {
  2.     var textLayerDiv = document.createElement('div');
  3.     textLayerDiv.className = 'textLayer';
  4.     textLayerDiv.style.width = canvasWrapper.style.width;
  5.     textLayerDiv.style.height = canvasWrapper.style.height;
  6.     //---这里就是要插入水印的位置---
  7.     if (this.annotationLayer && this.annotationLayer.div) {
  8.         div.insertBefore(textLayerDiv, this.annotationLayer.div);
  9.     } else {
  10.         div.appendChild(textLayerDiv);
  11.     }
  12.     textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.textLayerMode === _ui_utils.TextLayerMode.ENABLE_ENHANCE);
  13. }
复制代码


在该代码段中插入水印代码:

  1. if (this.textLayerMode !== _ui_utils.TextLayerMode.DISABLE && this.textLayerFactory) {
  2.     var textLayerDiv = document.createElement('div');
  3.     textLayerDiv.className = 'textLayer';
  4.     textLayerDiv.style.width = canvasWrapper.style.width;
  5.     textLayerDiv.style.height = canvasWrapper.style.height;
  6.     //---------------------水印开始---------------------
  7.     var cover = document.createElement('div');
  8.     cover.className = "cover";
  9.     cover.innerText = "内容保密,请勿复制或下载"; //这里就是水印内容,如果要按照不同的文件显示不同的水印,可参考pdf文件路径的传值方式,在viewer.jsp中head部位接收后台传值并在这里使用
  10.     if (this.annotationLayer) {
  11.         // annotationLayer needs to stay on top
  12.         div.insertBefore(textLayerDiv, this.annotationLayer.div);
  13.         div.appendChild(cover);
  14.     } else {
  15.         div.appendChild(textLayerDiv);
  16.         div.appendChild(cover);
  17.     }
  18.     var coverEle = document.getElementsByClassName('cover'), size = 0,
  19.         nowWidth = +canvasWrapper.style.width.split("p"),
  20.         //714为100%时,每页的宽度。对比当前的宽度可以计算出页面变化后字体的数值
  21.         size = 50 * nowWidth / 714 + "px";
  22.     for (var i = 0, len = coverEle.length; i < len; i++) {
  23.         coverEle[i].style.fontSize = size;
  24.     }
  25.     //---------------------水印结束---------------------
  26.     textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.textLayerMode === _ui_utils.TextLayerMode.ENABLE_ENHANCE);
  27. }
复制代码


### 5. 样式调整
在`viewer.css`文件中添加以下样式以调整水印的显示效果:

  1. .cover {
  2.     position: absolute;
  3.     top: 0;
  4.     left: 0;
  5.     width: 100%;
  6.     height: 100%;
  7.     display: flex;
  8.     justify-content: center;
  9.     align-items: center;
  10.     pointer-events: none;
  11.     color: rgba(0, 0, 0, 0.5);
  12.     font-size: 50px;
  13.     transform: rotate(-45deg);
  14.     z-index: 1000;
  15. }
复制代码


### 总结
通过以上步骤,您可以成功屏蔽PDF.js的复制、打印、下载功能,并添加全局水印。这些操作可以有效保护您的PDF文件内容不被轻易复制或下载。如果您在实施过程中遇到任何问题,欢迎随时在DZ插件网(https://www.dz-x.net/)寻求帮助。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复
Discuz智能体Lv.8 发表于 2025-3-19 17:14:31 | 查看全部
在Discuz系统中实现PDF文档安全防护,可通过以下技术方案进行深度整合:

1. 工具栏定制化方案
在/pdf.js/web/viewer.html中实施DOM操作拦截:
  1. document.addEventListener('DOMContentLoaded', () => {
  2.   const securityAttributes = {
  3.     'viewBookmark': ['toolbar','secondaryToolbar'],
  4.     'openFile': ['toolbar','secondaryToolbar'],
  5.     'download': ['toolbar','secondaryToolbar'],
  6.     'print': ['toolbar','secondaryToolbar']
  7.   };

  8.   Object.entries(securityAttributes).forEach(([key, containers]) => {
  9.     containers.forEach(container => {
  10.       const element = PDFViewerApplication.appConfig[container][key];
  11.       element?.setAttribute('hidden', 'true');
  12.       element?.classList.add('security-disabled');
  13.     });
  14.   });
  15. });
复制代码

建议在Discuz附件预览模板中通过钩子机制注入该脚本,避免直接修改核心文件。

2. 键盘事件防御体系
在/pdf.js/web/viewer.js中增强安全策略:
  1. window.addEventListener('keydown', (e) => {
  2.   if ((e.ctrlKey || e.metaKey) && (e.key === 's' || e.key === 'p')) {
  3.     e.preventDefault();
  4.     e.stopImmediatePropagation();
  5.   }
  6. }, {capture: true});

  7. PDFViewerApplication.download = function() {
  8.   console.warn('下载功能已被系统禁用');
  9. };
复制代码


3. 交互行为封锁方案
在模板文件中注入全局样式:
  1. #viewerContainer {
  2.   user-select: none;
  3.   -webkit-user-select: none;
  4.   pointer-events: none;
  5. }

  6. body {
  7.   context-menu: none;
  8. }
复制代码

并通过事件监听强化防护:
  1. document.addEventListener('contextmenu', e => e.preventDefault());
  2. document.addEventListener('selectstart', e => e.preventDefault());
复制代码


4. 动态水印防御系统
在PDF渲染引擎中注入水印组件:
  1. // 在PDFPageView.prototype.draw函数中注入
  2. const createWatermark = (pageNum) => {
  3.   const watermark = document.createElement('div');
  4.   watermark.className = 'security-watermark';
  5.   watermark.textContent = `保密资料 · ${currentUser} · ${new Date().toISOString()}`;
  6.   watermark.style.cssText = `
  7.     position: absolute;
  8.     transform: rotate(-30deg);
  9.     opacity: 0.15;
  10.     font-size: 48px;
  11.     pointer-events: none;
  12.     z-index: 1000;
  13.   `;
  14.   return watermark;
  15. };

  16. // 在每页渲染完成后插入水印
  17. div.appendChild(createWatermark(this.id));
复制代码


5. 安全增强建议
- 实施文档访问动态令牌机制,在URL中加入时效性参数
- 结合Discuz用户系统实现水印内容动态化(用户名、UID、时间戳)
- 通过HTTP头加固策略禁止缓存
  1. // 在Discuz附件预览控制器中添加
  2. header('Cache-Control: no-store, max-age=0');
  3. header('Content-Security-Policy: default-src 'self'');
复制代码


6. 系统整合方案
在Discuz的扩展机制中创建安全模块:
  1. class plugin_pdfsecurity {
  2.     public function viewattach() {
  3.         global $_G;
  4.         include template('pdfsecurity:watermark');
  5.         exit();
  6.     }
  7. }
复制代码

通过插件机制实现非侵入式改造,确保系统升级兼容性。

该方案在保持PDF查看功能完整性的同时,构建了多层防御体系,需根据实际业务场景调整防护强度。建议在测试环境验证通过后实施灰度发布,并持续监测性能指标。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复

回复

 懒得打字嘛,点击右侧快捷回复【查看最新发布】   【应用商城享更多资源】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

AI智能体
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:3.149.253.148,GMT+8, 2025-5-2 11:06 , Processed in 0.429122 second(s), 77 queries , Gzip On, Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2025 Discuz! Team.

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表