欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript實(shí)現(xiàn)多文件下載方法解析

 更新時(shí)間:2020年08月07日 09:12:50   作者:Barret李靖  
這篇文章主要介紹了JavaScript實(shí)現(xiàn)多文件下載方法解析,文章通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

對(duì)于文件的下載,可以說(shuō)是一個(gè)十分常見(jiàn)的話題,前端的很多項(xiàng)目中都會(huì)有這樣的需求,比如 highChart 統(tǒng)計(jì)圖的導(dǎo)出,在線圖片編輯中的圖片保存,在線代碼編輯的代碼導(dǎo)出等等。而很多時(shí)候,我們只給了一個(gè)鏈接,用戶需要右鍵點(diǎn)擊鏈接,然后選擇“另存為”,這個(gè)過(guò)程雖說(shuō)不麻煩,但還是需要兩步操作,倘若用戶想保存頁(yè)面中的多個(gè)鏈接文件,就得重復(fù)操作很多次,最常見(jiàn)的就是英語(yǔ)聽(tīng)力網(wǎng)站上的音頻下載,手都要點(diǎn)麻!

本文的目的是介紹如何利用 javascript 進(jìn)行多文件的下載,也就是當(dāng)用戶點(diǎn)擊某個(gè)鏈接或者按鈕的時(shí)候,同時(shí)下載多個(gè)文件。這里的“同時(shí)”用的不是很準(zhǔn)確,在現(xiàn)代瀏覽器中可以實(shí)現(xiàn)多文件的并行下載,而在一些老版本瀏覽器,如IE8-,此類(lèi)的瀏覽器就只能進(jìn)行單個(gè)文件的下載,但是我們可以讓多個(gè)文件依次保存下來(lái),算是串行下載吧~

若要要無(wú)視實(shí)現(xiàn)細(xì)節(jié),可以直接跳到第三部分,或者戳:

代碼封裝:lib.js

DEMO:javascript-multiple-download(HTTPS,第三個(gè)有bug,具體原因下面有說(shuō)明)

javascript-multiple-download(HTTP,測(cè)試正常)

一、文件類(lèi)型介紹及其特點(diǎn)

1. 一般類(lèi)型

平時(shí)比較常見(jiàn)的有 txt、png、jpg、zip、tar 等各種文件格式,這些文件格式中,一部分瀏覽器是會(huì)直接打開(kāi)鏈接顯示內(nèi)容的,而另外一部分,瀏覽器不識(shí)別響應(yīng)頭,或者不能解析對(duì)應(yīng)的格式,于是當(dāng)做文件直接下載下來(lái)了。如:

<a  rel="external nofollow" >file</a>

這句代碼,若直接點(diǎn)開(kāi)鏈接,瀏覽器將會(huì)直接下載該文件。

2. dataURL類(lèi)型

dataURL 也是十分常見(jiàn)的類(lèi)型,他可以作為 src 或者 url() 的參數(shù)送進(jìn)去。比較常見(jiàn)的有如下幾種:

文本: data:text/plain;這里是正文內(nèi)容。
圖片: data:image/jpg;base64,/9j/4AAQSkZJRgABAQEA....
  data:image/png;base64,/9j/4AAQSkZJRgABAQEA....

base64 是用的比較廣泛的一種數(shù)據(jù)格式。

Base64格式
data:[][;charset=][;base64],

Base64 在CSS中的使用:
.demoImg{ background-image: url("data:image/jpg;base64,/9j/4QMZRXhpZgAASUkqAAgAAAAL...."); }

Base64 在HTML中的使用:
<img width="40" height="30" src="data:image/jpg;base64,/9j/4QMZRXhpZgAASUkqAAgAAAAL...." />  

3. Blob 流

Blob 對(duì)象表示不可變的、包含原始數(shù)據(jù)的類(lèi)文件對(duì)象。具體的內(nèi)容可以參閱MDN文檔

他的使用也是特別的方便,如:

var aFileParts = ['<a id="a"><b id="b">hey!</b></a>'];
var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // the blob

Blob 接收兩個(gè)參數(shù),一個(gè)是數(shù)組類(lèi)型的數(shù)據(jù)對(duì)象,他可以是 ArrayBuffer、ArrayBufferView、Blob、String 等諸多類(lèi)型;第二個(gè)參數(shù)是 MINE 類(lèi)型設(shè)置。而本文我們要用到的是 URLcreateObjectURL() 這個(gè)函數(shù),他的作用是將一個(gè) URL 所代表的內(nèi)容轉(zhuǎn)化成一個(gè)DOMString,產(chǎn)生的結(jié)果是一個(gè) 文件對(duì)象 或者 Blob 對(duì)象。

4. 二進(jìn)制流

我們利用 File API 讀取文件的時(shí)候,拿到的是數(shù)據(jù)的二進(jìn)制流格式,這些類(lèi)型可以直接被 ArrayBuffer 等接收,本文中沒(méi)有用到,就不細(xì)說(shuō)了。

二、JavaScript 多文件下載

HTML5 中 a 標(biāo)簽多了一個(gè)屬性——download,用戶點(diǎn)擊鏈接瀏覽器會(huì)打開(kāi)并顯示該鏈接的內(nèi)容,若在鏈接中加了 download 屬性,點(diǎn)擊該鏈接不會(huì)打開(kāi)這個(gè)文件,而是直接下載。雖說(shuō)是比較好用,但低版本瀏覽器不兼容,這個(gè)在本節(jié)的 2 和 3 中將會(huì)講到解決方案。

在這里,我們可以利用屬性檢測(cè)UA 來(lái)判斷瀏覽器類(lèi)型:

h5Down = document.createElement("a").hasOwnProperty("download");
var h5Down = !/Trident|MSIE/.test(navigator.userAgent); // Trident 標(biāo)識(shí) IE11

1. a 標(biāo)簽 download 屬性的使用

注:FF5.0 / Safari5.0 / Opera11.1 / IE9.0 不支持 download 屬性

利用 download 屬性可以直接下載單個(gè)文件,若想點(diǎn)擊一次下載多個(gè)文件,就得稍加處理下了:

function downloadFile(fileName, content){
 var aLink = document.createElement("a"),
  evt = document.createEvent("HTMLEvents");

 evt.initEvent("click");
 aLink.download = fileName;
 aLink.href = content;

 aLink.dispatchEvent(evt);
}

download 屬性的作用除了讓瀏覽器忽略文件的 MIME 類(lèi)型之外,還會(huì)把該屬性的值作為文件名。你可以在 chrome 控制臺(tái)運(yùn)行這句程序:

downloadFile("barretlee.html", "./");

瀏覽器會(huì)提示是否保留(下載)該 html 文件。之前我們提到文件類(lèi)型還可能是 dataURL 或者是 Blob 流,為了讓程序也支持這些數(shù)據(jù)類(lèi)型,稍微修改下上面的函數(shù):

function downloadFile(fileName, content){
 var aLink = document.createElement('a');
  , blob = new Blob([content])
  , evt = document.createEvent("HTMLEvents");

 evt.initEvent("click");

 aLink.download = fileName;
 aLink.href = URL.createObjectURL(blob);
 aLink.dispatchEvent(evt);
}

new Blob([content]),現(xiàn)將文件轉(zhuǎn)換成一個(gè) Blog 流,然后,使用 URL.createObjectURL() 將其轉(zhuǎn)換成一個(gè) DOMString。這樣我們就支持 data64 和其他數(shù)據(jù)類(lèi)型的 content 了~

2. window.open 之后 execCommand("SaveAs")

上面也提到了,盡管 download 屬性是十分便利的 H5 利器,但低版本 IE 根本不賞臉,要說(shuō)方法,IE 還是有很多方式去轉(zhuǎn)換的,比如 ADOBE.STREAM 的 activeX 對(duì)象可以把文件轉(zhuǎn)換成文件流,然后寫(xiě)入到一個(gè)要保存的文件中。這里要談到的是略微方便一點(diǎn)的方式:先把內(nèi)容寫(xiě)到一個(gè)新開(kāi)的 window 對(duì)象中,然后利用 execCommand 執(zhí)行保存命令,就相當(dāng)于我們?cè)陧?yè)面上按下 Ctrl+S,這樣頁(yè)面內(nèi)的信息都會(huì) down 下來(lái)。

// 將文件在一個(gè) window 窗口中打開(kāi),并隱藏這個(gè)窗口。
var win = window.open("path/to/file.ext", "new Window", "width=0,height=0");
// 在 win 窗口中按下 ctrl+s 保存窗口內(nèi)容
win.document.execCommand("SaveAs", true, "filename.ext");
// 使用完了,關(guān)閉窗口
win.close();

這個(gè)過(guò)程十分明了,不過(guò)這里會(huì)存在一個(gè)問(wèn)題,并不是程序的問(wèn)題,而是瀏覽器的問(wèn)題,如果我們用 搜狗瀏覽器 或者 360瀏覽器 打開(kāi)新窗口的話,他會(huì)新開(kāi)一個(gè)標(biāo)簽頁(yè),而不是新開(kāi)一個(gè)窗口,更可惡的是部分瀏覽器攔截 window.open 的窗口(這個(gè)可以設(shè)置)。所以只好另覓他法了。

3. iframe 中操作

既然新開(kāi)一個(gè)窗口那么麻煩,我就在本窗口下完成工作~

function IEdownloadFile(fileName, contentOrPath){
 var ifr = document.createElement('iframe');

 ifr.style.display = 'none';
 ifr.src = contentOrPath;

 document.body.appendChild(ifr);


 // 保存頁(yè)面 -> 保存文件
 ifr.contentWindow.document.execCommand('SaveAs', false, fileName);
 document.body.removeChild(ifr);
}

一般的鏈接我們可以直接給 iframe 添加 src 屬性,然后執(zhí)行 saveAs 命令,倘若我們使用的是 data64 編碼的文件,這個(gè)怎么辦?

var isImg = contentOrPath.slice(0, 10) === "data:image";

// dataURL 的情況
isImg && ifr.contentWindow.document.write("<img src='" + 
  contentOrPath + "' />");

這個(gè)也比較好處理,直接把文件寫(xiě)入到 iframe 中,然后在執(zhí)行保存。

三、代碼的封裝與接口介紹

1. 代碼的封裝以及相關(guān) DEMO

封裝:lib.js

DEMO:javascript-multiple-download(HTTPS,第三個(gè)有bug)

javascript-multiple-download(HTTP,測(cè)試正常)

Bug 說(shuō)明,經(jīng)過(guò)一番細(xì)節(jié)處理之后,基本兼容各個(gè)瀏覽器,我把代碼放在 https://raw.github.com 上托管,可能因?yàn)槭?https 傳輸,第三個(gè)測(cè)試中報(bào)錯(cuò)了,報(bào)錯(cuò)的具體內(nèi)容是:HTTPS 安全受到 http://rawgithub.com/barretlee/javascript-multiple-download/master/file/test.jpg 的威脅,而 test.txt 文件沒(méi)有報(bào)錯(cuò)。放到 http 協(xié)議下測(cè)試運(yùn)行結(jié)果是可觀的。(這點(diǎn)我沒(méi)有去深究,肯定是有深層安全方面原因的,難道就因?yàn)樗?jpg圖片格式? 謝@屈屈提醒,跨協(xié)議傳輸存在安全問(wèn)題)后面的 demo 我放在 BAE 上,沒(méi)有問(wèn)題,不過(guò)沒(méi)測(cè)試 safari 和 opera。

2. 接口的調(diào)用

提供了三個(gè)接口,支持單文件下載,多文件下載,多文件下載自定義命名。

1)單文件下載

Downer("./file/test.txt");

2)多文件下載

Downer(["./file/test.txt","./file/test.txt"]);

3)多文件下載自定義命名

Downer({
 "1.txt":"./file/test.txt",
 "2.jpg":"./file/test.jpg"
}); 

文件的 URL 如 ./file/test.jpg 都可以改成 base64 或者其他格式,如:

Downer({
  //這是一個(gè)很長(zhǎng)的 dataURI,我用負(fù)的text-indent隱藏了,可直接復(fù)制
 "data64.jpg" : "data:image/jpg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAAYADsDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9NgKKK8w8beO/EMVzGdJ08W2jW2t2WnXGpLdx+e7PPEkii3eJgYj5mwsJFkzkquAC3VFc0lFf10/UOlz1CivO9H+LEmreP7jw8mlBrLfPDa6nC1y0cksX30Z2t1hGCHBEcsjAqQVHOJPCfjnxFc+HNU1rxPpmh6Vp9mt232i01WWXmGV0IdXt0CrhD8+45xnaM4A00uZ9rgtZcq3vb5noFLXCfDz4j3vjbT9XM+hSabqdhtItWFxGswZCybTc28DjJDAkx7fRjzi/qmv6zH8LdR1m6sP+Ef12PSprprPzkufssyxMwXeBtfBA5xg0OLi2n/Vwh+8aUep1gFLXGeKhqmj+FtGmt9fvvtVvfWMc9w0VsWvUkuI43WUeVtAIcnMYQggYI6Hs6lqwk7pPuNrkPEHwn8N+KNRkvdQh1BpZJY7ho7fVru3haWPbslMUcqpvXYhD7d2VU54FFFNNxd1uPyJIfhb4dt/EkOuxwXy6hBNJPD/xNLryImkz5myHzPLUNkllC4J5IyAaWP4W+GY7+/uzp7yy3sc8UiTXc0kUazHdMIo2cpDvPLeWFyeTRRRd9wH6B8NNB8NyapJZx38kmpxrFePe6pdXbTKAQMmaRjkAkZHOMDOAKmbwLp9n8Pp/CGkr/Zmm/wBnyadbjLS+QjIUB+ZstjPdsn1oopOTfUa91prdf1+hFrfhnWNb0HSLCTVrGOaC6tbi+mXT323CwyrJtiXzv3RZkXljJgZ4PWuooopNtkpWVkf/2Q==" 
});

這里只做到了 chrome 兼容,IE 下懶得去看了,這個(gè)需求很少見(jiàn)!

四、服務(wù)器支持與后端實(shí)現(xiàn)

1. 后端實(shí)現(xiàn)

不使用前端,直接后端實(shí)現(xiàn)的原理,就是在響應(yīng)頭中加入一些特殊的標(biāo)記,如前端發(fā)送這樣的請(qǐng)求:

function download(path) {
 var ifrm = document.getElementById(frame);
 ifrm.src = "download.php?path="+path;
}

后端的響應(yīng)為

<?php 
 header("Content-Type: application/octet-stream");
 header("Content-Disposition: attachment; filename=".$_GET['path']);
 readfile($_GET['path']);
?>

告訴瀏覽器這是一個(gè)流文件,作為附件方式發(fā)送給你,請(qǐng)忽略 MINE type,直接保存。

2. 服務(wù)器配置

若后臺(tái)是 apche 作為服務(wù)器,可以配置 htaccess 文件:

<filesmatch "\.(zip|rar)$"="">
Header set Content-Disposition attachment
</filesmatch>

意思是只要請(qǐng)求的是 zip 或者 rar 類(lèi)型的文件,那么就添加一個(gè) Content-Disposition:attachment 的響應(yīng)頭。這樣就可以在 php 代碼中省略麻煩的操作。

五、小結(jié)

由于行文倉(cāng)促,文中會(huì)有不少錯(cuò)誤,對(duì)多文件下載有更好的提議,希望提出來(lái)共同分享!

實(shí)現(xiàn)多文件下載的方式肯定不止上面提到的幾種,而且我這里封裝的代碼并沒(méi)有在FF safari opera 中實(shí)現(xiàn),因?yàn)樗麄冞€沒(méi)兼容 download 屬性,具體情況可以查看 caniuse。建議在項(xiàng)目中把這樣的事情交給后端,幾句代碼可以搞定。

六、參考資料

在瀏覽器端用JS創(chuàng)建和下載文件 AlloyTeam

Starting file download with Javascript Ahzaz's Blog

Blob 流 MDN

到此這篇關(guān)于JavaScript實(shí)現(xiàn)多文件下載方法解析的文章就介紹到這了,更多相關(guān)JavaScript多文件下載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Echart折線圖手柄觸發(fā)事件示例詳解

    Echart折線圖手柄觸發(fā)事件示例詳解

    這篇文章主要給大家介紹了關(guān)于Echart折線圖手柄觸發(fā)事件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • Webpack按需加載打包c(diǎn)hunk命名的方法

    Webpack按需加載打包c(diǎn)hunk命名的方法

    這篇文章主要給大家介紹了關(guān)于Webpack按需加載打包c(diǎn)hunk命名的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Webpack具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • ie中js創(chuàng)建checkbox默認(rèn)選中問(wèn)題探討

    ie中js創(chuàng)建checkbox默認(rèn)選中問(wèn)題探討

    js創(chuàng)建checkbox默認(rèn)選中在某些特殊情況下還是比較實(shí)用的,下面有個(gè)不錯(cuò)的示例,大家可以參考下
    2013-10-10
  • 原生js實(shí)現(xiàn)俄羅斯方塊

    原生js實(shí)現(xiàn)俄羅斯方塊

    這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)俄羅斯方塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • 老生常談Bootstrap媒體對(duì)象

    老生常談Bootstrap媒體對(duì)象

    下面小編就為大家?guī)?lái)一篇老生常談Bootstrap媒體對(duì)象。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • H5基于iScroll實(shí)現(xiàn)下拉刷新和上拉加載更多

    H5基于iScroll實(shí)現(xiàn)下拉刷新和上拉加載更多

    這篇文章主要為大家詳細(xì)介紹了H5基于iScroll實(shí)現(xiàn)下拉刷新和上拉加載更多效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • JavaScript中各種編碼解碼函數(shù)的區(qū)別和注意事項(xiàng)

    JavaScript中各種編碼解碼函數(shù)的區(qū)別和注意事項(xiàng)

    JavaScript 中encodeURI,encodeURIComponent與escape的區(qū)別和注
    2010-08-08
  • 去除字符串左右兩邊的空格(實(shí)現(xiàn)代碼)

    去除字符串左右兩邊的空格(實(shí)現(xiàn)代碼)

    下面小編就為大家?guī)?lái)一篇去除字符串左右兩邊的空格(實(shí)現(xiàn)代碼)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考
    2016-05-05
  • JavaScript新增樣式規(guī)則(推薦)

    JavaScript新增樣式規(guī)則(推薦)

    這篇文章主要介紹了JavaScript新增樣式規(guī)則(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • javascript編寫(xiě)貪吃蛇游戲

    javascript編寫(xiě)貪吃蛇游戲

    這篇文章主要介紹了javascript編寫(xiě)貪吃蛇游戲的代碼,非常簡(jiǎn)單,也很好玩,有需要的童鞋們可以參考下。
    2015-07-07

最新評(píng)論