道客這樣的文檔網(wǎng)站,對(duì)于很多PDF都要求積分,積分不到不讓下載。
這個(gè)不是很爽,因?yàn)槲译y得去上面下載一份找了半天的文檔資料,還要我注冊(cè),注冊(cè)了還不算還要我拼命賺積分,不賺積分就要充值,太惡劣了。
作為一個(gè)崇尚開源/自由的人——其實(shí)主要是我不舍得花錢,要想辦法來解決這個(gè)問題。
這類PDF文檔網(wǎng)站都提供文件的預(yù)覽,甚至是全文預(yù)覽,只不過下載的時(shí)候有積分這道坎。
而他們的全文預(yù)覽,不是直接用的PDF,而是把PDF內(nèi)容寫入到Canvas中,而Canvas的內(nèi)容不讓下載。
既然是寫入到Canvas中,那就由不得你不讓我下載了。
下面是兩個(gè)函數(shù),專門處理這個(gè)問題:
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');
});
}
思路其實(shí)很簡(jiǎn)單。
Canvas對(duì)象可以把其中的內(nèi)容(無(wú)論是普通的2d的context,還是webgl或者webgl2)導(dǎo)出為blob(或者base64格式的dataURL)。
而后,window的URL組件可以將blob對(duì)象轉(zhuǎn)化為可以用來下載或者讓別的頁(yè)面使用的objectURL(這個(gè)要注意,使用完以后要釋放資源,不然內(nèi)存就爆了),用來進(jìn)一步給IMG或者BACKGROUNDIMAGE或者別的CANVAS使用,而且也可以用來作為link的目標(biāo)對(duì)象。
這樣,我們先把canvas內(nèi)容轉(zhuǎn)化為blob,然后再轉(zhuǎn)化為objectURL,最后新建一個(gè)link,并模擬點(diǎn)擊,從而實(shí)現(xiàn)自動(dòng)下載。
這里還可以做得更加完善一點(diǎn),那就是獲取每個(gè)canvas的實(shí)際尺寸(canvas的獲取context,而一個(gè)context帶有實(shí)際繪制區(qū)的寬高屬性),然后新建一個(gè)canvas將所有目標(biāo)canvas的內(nèi)容繪制到這個(gè)新的canvas上(注意上下銜接,使用context的height屬性來往下移動(dòng)并拼接),最后將這個(gè)新的canvas所謂真正要導(dǎo)出的目標(biāo),下載到本地。
這里就不給代碼了。