道客這樣的文檔網站,對于很多PDF都要求積分,積分不到不讓下載。
這個不是很爽,因為我難得去上面下載一份找了半天的文檔資料,還要我注冊,注冊了還不算還要我拼命賺積分,不賺積分就要充值,太惡劣了。
作為一個崇尚開源/自由的人——其實主要是我不舍得花錢,要想辦法來解決這個問題。
這類PDF文檔網站都提供文件的預覽,甚至是全文預覽,只不過下載的時候有積分這道坎。
而他們的全文預覽,不是直接用的PDF,而是把PDF內容寫入到Canvas中,而Canvas的內容不讓下載。
既然是寫入到Canvas中,那就由不得你不讓我下載了。
下面是兩個函數,專門處理這個問題:
var saveCanvas = (cvs, filename) => {
cvs.toBlob(blob => {
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.download = filename || 'canvas.png';
a.click();
});
};
var canvas2File = filename => {
filename = filename || 'canvasPDF';
var cvs = document.querySelectorAll('canvas');
[].forEach.call(cvs, (c, i) => {
saveCanvas(c, filename + '_' + (i + 1) + '.png');
});
}
思路其實很簡單。
Canvas對象可以把其中的內容(無論是普通的2d的context,還是webgl或者webgl2)導出為blob(或者base64格式的dataURL)。
而后,window的URL組件可以將blob對象轉化為可以用來下載或者讓別的頁面使用的objectURL(這個要注意,使用完以后要釋放資源,不然內存就爆了),用來進一步給IMG或者BACKGROUNDIMAGE或者別的CANVAS使用,而且也可以用來作為link的目標對象。
這樣,我們先把canvas內容轉化為blob,然后再轉化為objectURL,最后新建一個link,并模擬點擊,從而實現自動下載。
這里還可以做得更加完善一點,那就是獲取每個canvas的實際尺寸(canvas的獲取context,而一個context帶有實際繪制區的寬高屬性),然后新建一個canvas將所有目標canvas的內容繪制到這個新的canvas上(注意上下銜接,使用context的height屬性來往下移動并拼接),最后將這個新的canvas所謂真正要導出的目標,下載到本地。
這里就不給代碼了。