前情提要
如果說鎖頭是拿來防君子,
那麼 PDF,基本上就是拿來考驗人性的。
你辛苦整理的教材、簡報、筆記,
只要一變成 PDF,命運通常只有兩條路:
- 被整包下載
- 被無限轉傳
我們來用一個前端角度很壞、但很實際的做法,
來解決這個還滿G8靠北的白爛議題。
程式碼
<!DOCTYPE html>
<html>
<head>
<title>PDF Viewer</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
</head>
<body>
<input type="file" id="pdf-file">
<div id="pdf-viewer"></div>
<script>
const fileInput = document.getElementById('pdf-file');
const pdfViewer = document.getElementById('pdf-viewer');
fileInput.addEventListener('change', () => {
const file = fileInput.files[0];
const reader = new FileReader();
reader.onload = function () {
const data = new Uint8Array(this.result);
pdfjsLib.getDocument(data).promise.then(pdf => {
pdf.getPage(15).then(page => {
const canvas = document.createElement('canvas');
const viewport = page.getViewport({ scale: 1 });
const ctx = canvas.getContext('2d');
canvas.width = viewport.width;
canvas.height = viewport.height;
page.render({
canvasContext: ctx,
viewport
}).promise.then(() => {
pdfViewer.appendChild(canvas);
});
});
});
};
reader.readAsArrayBuffer(file);
});
</script>
</body>
</html>
貼到線上編輯器跑一次,你就會知道它在玩什麼。
這段程式在搞什麼鬼
乍看之下,它好像只是一個「PDF 預覽」。
但實際上,它完全沒打算讓你「使用 PDF」。
整個流程是這樣:
- 使用者選擇檔案
- JavaScript 把 PDF 拆開
- 指定某一頁
- 重新畫成一張 canvas
注意這個關鍵轉換點:
從這一刻開始,畫面上出現的東西,
已經不是文件,而是「結果」。
為什麼這樣比較難抓
因為你給出去的不是:
- 可選取的文字
- 原始檔案結構
- 可以另存的 PDF
而是:
- 一塊畫布
- 一堆像素
- 一張「你只能看」的圖
想拿?門都沒有你要的話就要費盡心力。
心得
原本乏味、無聊、注定被抓走的 PDF,
竟然可以用一個前端技巧,
轉化成一個「有距離感」的展示物。
不阻止你看,而是改變你拿的方式。
這觀念有屌到!