有時候需要在前端側對於動態生成的內容進行下載,比如頁面上某一段文本信息,再比如對頁面進行分享的時候,希望分享圖片是頁面內容的實時截圖,此時,這個圖片就是動態的,純HTML顯然是無法滿足我們的需求的,借助JS和其它一些HTML5特性,例如,將頁面元素轉換到canvas
上,然后再轉成圖片進行下載。
原理其實很簡單,我們可以將文本或者JS字符串信息借助Blob轉換成二進制,然后,作為<a>
元素的href
屬性,配合download
屬性,實現下載。
代碼也比較簡單,如下示意(兼容Chrome和Firefox):
<script>
function funcDownload (content, filename) {
// 創建隱藏的可下載鏈接
var eleLink = document.createElement('a');
eleLink.download = filename;
eleLink.style.display = 'none';
// 字符內容轉變成blob地址
var blob = new Blob([content]);
eleLink.href = URL.createObjectURL(blob);
// 觸發點擊
document.body.appendChild(eleLink);
eleLink.click();
// 然后移除
document.body.removeChild(eleLink);
}
function dn (){
var ss = document.querySelector('html').outerHTML;
funcDownload(ss, 'ceshi.html')
}
</script>
其中,content
指需要下載的文本或字符串內容,filename
指下載到系統中的文件名稱。
以上代碼可以將當前整個網頁下載為html文件,但是對於網頁里面外鏈的一些資源,則無法顯示。
在Chrome瀏覽器下,模擬點擊創建的<a>
元素即使不append
到頁面中,也是可以觸發下載的,但是在Firefox瀏覽器中卻不行,因此,上面的funDownload()
方法有一個appendChild
和removeChild
的處理,就是為了兼容Firefox瀏覽器。
1、URL.createObjectURL()方法會根據傳入的參數創建一個指向該參數對象的URL,這個URL的生命僅存在於它被創建的這個document里,新的對象URL指向執行的File對象或者是Blob對象。
objectURL = URL.createObjectURL(blob || file);
參數:File對象或者Blob對象。這里大概說下File對象和Blob對象:
File對象:就是一個文件,比如我用input type="file"標簽來上傳文件,那么里面的每個文件都是一個File對象。
Blob對象:就是二進制數據,比如通過new Blob()創建的對象就是Blob對象,又比如在XMLHttpRequest里,如果指定responseType為blob,那么得到的返回值也是一個blob對象。
注意點:每次調用createObjectURL的時候,一個新的URL對象就被創建了。即使你已經為同一個文件創建過一個URL.;如果你不再需要這個對象,要釋放它,需要使用URL.revokeObjectURL()方法.,當頁面被關閉,瀏覽器會自動釋放它,但是為了最佳性能和內存使用,當確保不再用得到它的時候就應該釋放它。
2、URL.revokeObjectURL()方法會釋放一個通過URL.createObjectURL()創建的對象URL,當你要已經用過了這個對象URL,然后要讓瀏覽器知道這個URL已經不再需要指向對應的文件的時候,就需要調用這個方法。具體的意思就是說,一個對象URL使用這個url是可以訪問到指定的文件的,但是我可能只需要訪問一次,一旦已經訪問到了,這個對象URL就不再需要了就被釋放掉,被釋放掉以后,這個對象URL就不再指向指定的文件了。比如一張圖片,我創建了一個對象URL,然后通過這個對象URL,我頁面里加載了這張圖,既然已經被加載,並且不需要再次加載這張圖,那我就把這個對象URL釋放,然后這個URL就不再指向這張圖了。
window.URL.revokeObjectURL(objectURL);
//objectURL 是一個通過URL.createObjectURL()方法創建的對象URL.