您好,登錄后才能下訂單哦!
這篇文章主要介紹JavaScrip基于url如何實現圖片下載,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
1.H5 download屬性
function downFile(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); };
downFile(下載地址, 保存名稱);
2.iframe方式
// if (typeof(download.iframe) == 'undefined') { // var iframe = document.createElement('iframe'); // download.iframe = iframe; // document.body.appendChild(download.iframe); // }; // download.iframe.src = newdownloadUrl; // download.iframe.style.display = "none";
3.form方式
// var $eleForm = $("<form method='get'></form>"); // $eleForm.attr("action", "https://codeload.github.com/douban/douban-client/legacy.zip/master"); // $eleForm.attr("action", url); // $(document.body).append($eleForm); // $eleForm.submit();
downloadIamge(imgsrc, name) {//下載圖片地址和圖片名 let image = new Image(); // 解決跨域 Canvas 污染問題 image.setAttribute("crossOrigin", "anonymous"); image.onload = function() { let canvas = document.createElement("canvas"); canvas.width = image.width; canvas.height = image.height; let context = canvas.getContext("2d"); context.drawImage(image, 0, 0, image.width, image.height); let url = canvas.toDataURL("image/png"); //得到圖片的base64編碼數據 let a = document.createElement("a"); // 生成一個a元素 let event = new MouseEvent("click"); // 創建一個單擊事件 a.download = name || "photo"; // 設置圖片名稱 a.href = url; // 將生成的URL設置為a.href屬性 a.dispatchEvent(event); // 觸發a的單擊事件 }; image.src = imgsrc; },
原理
我們先看看 download 的使用方法:
<a href="http://somehost/somefile.zip" rel="external nofollow" rel="external nofollow" download="filename.zip">Download file</a>
看看上面的代碼,只要為 <a> 標簽添加 download 屬性,我們點擊這個鏈接的時候就會自動下載文件了~
順便說下,download 的屬性值是可選的,它用來指定下載文件的文件名。像上面的例子中,我們下載到本地的文件名就會是 filename.zip 拉,如果不指定的話,它就會是 somefile.zip 這個名字拉!
看到這里,你可能會說,坑爹啊,這明明是用 HTML 5 的新特性來實現下載文件嘛,說好的用 JavaScript 下載文件呢?
事實上,用 JavaScript 來下載文件也是利用這一特性來實現的,我們的 JavaScript 代碼不外乎就是:
翻譯成 JavaScript 代碼就是:
var a = document.createElement('a'); var url = window.URL.createObjectURL(blob); var filename = 'what-you-want.txt'; a.href = url; a.download = filename; a.click(); window.URL.revokeObjectURL(url);
好拉,是不是看到有個陌生的東東呢?
window.URL
window.URL 里面有兩個方法:
createObjectURL 用 blob 對象來創建一個 object URL(它是一個 DOMString),我們可以用這個 object URL 來表示某個 blob 對象,這個 object URL 可以用在 href 和 src 之類的屬性上。
revokeObjectURL 釋放由 createObjectURL 創建的 object URL,當該 object URL 不需要的時候,我們要主動調用這個方法來獲取最佳性能和內存使用。
知道了這兩個方法之后,我們再回去看看上面的例子就很容易理解了吧!只是用 blob 對象來創建一條 URL,然后讓 <a> 標簽引用該 URL,然后觸發個點擊事件,就可以下載文件了!
那么問題來了,blob 對象哪里來?
Blob 對象
Blob 全稱是 Binary large object,它表示一個類文件對象,可以用它來表示一個文件。根據 MDN 上面的說法,File API 也是基于 blob 來實現的。
由于本文的主題是講 JavaScript 下載文件,那我們構建 blob 的方式就是通過服務器返回的文件來創建 blob 拉!
而最簡單的方式就是用 fetch API 了,我們可以整合上面的例子:
fetch('http://somehost/somefile.zip').then(res => res.blob().then(blob => { var a = document.createElement('a'); var url = window.URL.createObjectURL(blob); var filename = 'myfile.zip'; a.href = url; a.download = filename; a.click(); window.URL.revokeObjectURL(url); }))
很簡單對吧!
你可能會問,何必這么麻煩呢?直接寫成下面這樣不就好了:
<a href="http://somehost/somefile.zip" rel="external nofollow" rel="external nofollow" download="myfile.zip">Download file</a>
嗯,對于這種寫法,我只能說,你做的太正確了!如果你要下載的是已經存在服務器上面的靜態文件的話,那么寫成這樣是最方便的。瀏覽器會幫你處理整個下載過程,不需要你干涉。如果你用 blob 的方式來下載文件的話,會有下面這些限制的:
限制一:不同瀏覽器對 blob 對象有不同的限制
具體看看下面這個表格(出自 FileSaver.js):
Browser | Constructs as | Filenames | Max Blob Size | Dependencies |
---|---|---|---|---|
Firefox 20+ | Blob | Yes | 800 MiB | None |
Firefox < 20 | data: URI | No | n/a | Blob.js |
Chrome | Blob | Yes | 500 MiB | None |
Chrome for Android | Blob | Yes | 500 MiB | None |
Edge | Blob | Yes | ? | None |
IE 10+ | Blob | Yes | 600 MiB | None |
Opera 15+ | Blob | Yes | 500 MiB | None |
Opera < 15 | data: URI | No | n/a | Blob.js |
Safari 6.1+* | Blob | No | ? | None |
Safari < 6 | data: URI | No | n/a | Blob.js |
限制二:構建完 blob 對象后才會轉換成文件
這一點限制對小文件(幾十kb)可能沒什么影響,但對稍微大一點的文件影響就很大了。試想,用戶要下載一個 100mb 的文件,如
果他點擊了下載按鈕之后沒看到下載提示的話,他肯定會繼續按,等他按了幾次之后還沒看到下載提示時,他就會抱怨我們的網站,然后離開了。
然而事實上下載的的確確發生了,只是要等到下載完文件之后才能構建 blob 對象,再轉化成文件。而且,用戶再觸發多幾次下載就會造成一些資源上的浪費。
因此,如果是要下載大文件的話,還是推薦直接創建一個 <a> 標簽拉~
寫 html 也好,寫 JavaScript 動態創建也好,用自己喜歡的方式去創建就好了。
為什么要用 JavaScript 下載文件
好拉,說了半天,其實我們一直說的都是:「不要用 JavaScript 下載文件拉,限制多多,又不好用,直接用 html 就好拉,簡單方便又快捷」這個論調。
事實上也確實如此,但有些時候我們確實需要通過 JavaScript 來做一些預處理。
權限校驗
有些時候,我們需要對下載做一些限制,最常見的就是權限校驗了,如檢查該用戶是否有下載的權限,是否有高速下載的權限等等。這時候,我們可以利用 JavaScript 做一些預處理。如:
fetch('http://somehost/check-permission', options).then(res => { if (res.code === 0) { var a = document.createElement('a'); var url = res.data.url; var filename = 'myfile.zip'; a.href = url; a.download = filename; a.click(); } else { alert('You have no permission to download the file!'); } });
在這個例子里面,我們沒有用 blob 來構建 URL,而是通過后端服務器來計算出用戶的下載鏈接,然后再利用之前提到的動態創建 <a> 標簽的方式來實現下載,很簡單吧!
動態文件
動態生成文件然后返回給客戶端也是一個很常見的需求,譬如我們有時候需要做導出數據的功能,把數據庫中的某些數據導出到 Excel 中,然后再返回客戶端。
這時候我們就不能簡單的指定 href 屬性,因為對應的 URL 并不存在。
我們只能通過 JavaScript 對服務器發出一個請求,通知它去生成某個文件,然后把對應的 URL 返回給客戶端。
有沒有感覺這個過程和上面「權限校驗」一節很像?肯定拉,因為我們只是對 URL 做了一些預處理而已嘛~
以上是JavaScrip基于url如何實現圖片下載的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。