feat(PdfPreview): 增强PDF预览的安全性和交互限制
添加CSS样式和事件监听器防止PDF内容被选择、复制或保存 禁用工具栏和调整默认语言为中文
Showing
1 changed file
with
73 additions
and
6 deletions
| ... | @@ -5,7 +5,7 @@ | ... | @@ -5,7 +5,7 @@ |
| 5 | <template> | 5 | <template> |
| 6 | <van-popup v-if="show" :show="show" @update:show="emit('update:show', $event)" position="right" | 6 | <van-popup v-if="show" :show="show" @update:show="emit('update:show', $event)" position="right" |
| 7 | :style="{ height: '100%', width: '100%' }"> | 7 | :style="{ height: '100%', width: '100%' }"> |
| 8 | - <div id="pdf-container"></div> | 8 | + <div id="pdf-container" class="pdf-no-select"></div> |
| 9 | <van-button class="close-btn" type="default" icon="cross" round @click="emit('update:show', false)" /> | 9 | <van-button class="close-btn" type="default" icon="cross" round @click="emit('update:show', false)" /> |
| 10 | <van-overlay :show="loading"> | 10 | <van-overlay :show="loading"> |
| 11 | <div class="wrapper" @click.stop> | 11 | <div class="wrapper" @click.stop> |
| ... | @@ -68,20 +68,44 @@ const initPdfViewer = () => { | ... | @@ -68,20 +68,44 @@ const initPdfViewer = () => { |
| 68 | navShow: true, | 68 | navShow: true, |
| 69 | navigationShow: false, | 69 | navigationShow: false, |
| 70 | pdfViewResize: true, | 70 | pdfViewResize: true, |
| 71 | - toolShow: true, | 71 | + toolShow: false, |
| 72 | - download: false, | 72 | + download: false, // 禁用下载功能 |
| 73 | - clearScale: 1.5, | 73 | + clearScale: 1.75, |
| 74 | fileName: props.title, | 74 | fileName: props.title, |
| 75 | - lang: "en", | 75 | + lang: "zh", |
| 76 | - print: false, | 76 | + print: false, // 禁用打印功能 |
| 77 | watermarkOptions: undefined, | 77 | watermarkOptions: undefined, |
| 78 | customPdfOption: { | 78 | customPdfOption: { |
| 79 | // customPdfOption是 pdfjs getDocument 函数中一些配置参数 具体可参考 https://mozilla.github.io/pdf.js/api/draft/module-pdfjsLib.html#~DocumentInitParameters | 79 | // customPdfOption是 pdfjs getDocument 函数中一些配置参数 具体可参考 https://mozilla.github.io/pdf.js/api/draft/module-pdfjsLib.html#~DocumentInitParameters |
| 80 | cMapPacked: true, //指定 CMap 是否是二进制打包的 | 80 | cMapPacked: true, //指定 CMap 是否是二进制打包的 |
| 81 | cMapUrl: "https://cdn.jsdelivr.net/npm/pdfjs-dist@2.2.228/cmaps/", //预定义 Adobe CMaps 所在的 URL。可解决字体加载错误 | 81 | cMapUrl: "https://cdn.jsdelivr.net/npm/pdfjs-dist@2.2.228/cmaps/", //预定义 Adobe CMaps 所在的 URL。可解决字体加载错误 |
| 82 | }, | 82 | }, |
| 83 | + // 禁用右键菜单和文本选择 | ||
| 84 | + selectConfig: undefined, // 禁用文本选择功能 | ||
| 83 | } | 85 | } |
| 84 | }); | 86 | }); |
| 87 | + | ||
| 88 | + // 添加额外的事件监听器来防止长按保存 | ||
| 89 | + const pdfContainer = document.querySelector("#pdf-container"); | ||
| 90 | + if (pdfContainer) { | ||
| 91 | + // 防止上下文菜单(右键菜单) | ||
| 92 | + pdfContainer.addEventListener('contextmenu', (e) => { | ||
| 93 | + e.preventDefault(); | ||
| 94 | + return false; | ||
| 95 | + }); | ||
| 96 | + | ||
| 97 | + // 防止长按选择 | ||
| 98 | + pdfContainer.addEventListener('selectstart', (e) => { | ||
| 99 | + e.preventDefault(); | ||
| 100 | + return false; | ||
| 101 | + }); | ||
| 102 | + | ||
| 103 | + // 防止拖拽 | ||
| 104 | + pdfContainer.addEventListener('dragstart', (e) => { | ||
| 105 | + e.preventDefault(); | ||
| 106 | + return false; | ||
| 107 | + }); | ||
| 108 | + } | ||
| 85 | }); | 109 | }); |
| 86 | }; | 110 | }; |
| 87 | </script> | 111 | </script> |
| ... | @@ -93,6 +117,49 @@ const initPdfViewer = () => { | ... | @@ -93,6 +117,49 @@ const initPdfViewer = () => { |
| 93 | height: 100%; | 117 | height: 100%; |
| 94 | } | 118 | } |
| 95 | 119 | ||
| 120 | +/* 防止PDF图片被长按保存的样式 */ | ||
| 121 | +.pdf-no-select { | ||
| 122 | + -webkit-user-select: none; /* Safari */ | ||
| 123 | + -moz-user-select: none; /* Firefox */ | ||
| 124 | + -ms-user-select: none; /* IE10+/Edge */ | ||
| 125 | + user-select: none; /* Standard */ | ||
| 126 | + -webkit-touch-callout: none; /* iOS Safari */ | ||
| 127 | + -webkit-tap-highlight-color: transparent; /* 移除点击高亮 */ | ||
| 128 | + pointer-events: auto; /* 保持可点击 */ | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +/* 深度选择器,防止PDF内部图片被保存 */ | ||
| 132 | +:deep(.pdf-no-select img) { | ||
| 133 | + -webkit-user-select: none; | ||
| 134 | + -moz-user-select: none; | ||
| 135 | + -ms-user-select: none; | ||
| 136 | + user-select: none; | ||
| 137 | + -webkit-touch-callout: none; | ||
| 138 | + -webkit-tap-highlight-color: transparent; | ||
| 139 | + pointer-events: none; /* 禁用图片的所有交互 */ | ||
| 140 | + -webkit-user-drag: none; /* 禁止拖拽 */ | ||
| 141 | + -khtml-user-drag: none; | ||
| 142 | + -moz-user-drag: none; | ||
| 143 | + -o-user-drag: none; | ||
| 144 | + user-drag: none; | ||
| 145 | +} | ||
| 146 | + | ||
| 147 | +/* 防止右键菜单 */ | ||
| 148 | +:deep(.pdf-no-select canvas) { | ||
| 149 | + -webkit-user-select: none; | ||
| 150 | + -moz-user-select: none; | ||
| 151 | + -ms-user-select: none; | ||
| 152 | + user-select: none; | ||
| 153 | + -webkit-touch-callout: none; | ||
| 154 | + -webkit-tap-highlight-color: transparent; | ||
| 155 | + pointer-events: none; | ||
| 156 | + -webkit-user-drag: none; | ||
| 157 | + -khtml-user-drag: none; | ||
| 158 | + -moz-user-drag: none; | ||
| 159 | + -o-user-drag: none; | ||
| 160 | + user-drag: none; | ||
| 161 | +} | ||
| 162 | + | ||
| 96 | .close-btn { | 163 | .close-btn { |
| 97 | position: fixed; | 164 | position: fixed; |
| 98 | right: 20px; | 165 | right: 20px; | ... | ... |
-
Please register or login to post a comment