├── README.md
├── file
├── test.jpg
├── test.rar
└── test.txt
├── lib.js
└── test
└── test.html
/README.md:
--------------------------------------------------------------------------------
1 | JavaScript多文件下载
2 | ============================
3 |
4 | ### 代码的封装以及相关 DEMO
5 |
6 | DEMO1:[javascript-multiple-download](http://rawgithub.com/barretlee/javascript-multiple-download/master/test/test.html) (HTTPS,第三个有bug)
7 |
8 | DEMO2:[javascript-multiple-download](http://qianduannotes.duapp.com/demo/javascript-multiple-download/test/test.html) (HTTP,测试正常)
9 |
10 | Bug 说明,经过一番细节处理之后,基本兼容各个浏览器,我把代码放在 https://raw.github.com 上托管,可能因为是 https 传输,第三个测试中报错了,报错的具体内容是:HTTPS 安全受到 http://rawgithub.com/barretlee/javascript-multiple-download/master/file/test.jpg 的威胁,而 test.txt 文件没有报错。放到 http 协议下测试运行结果是可观的。(这点我没有去深究,肯定是有深层安全方面原因的,难道就因为他是 jpg图片格式?)后面的 demo 我放在 BAE 上,没有问题,不过没测试 safari 和 opera。
11 |
12 | ### 接口的调用
13 |
14 | 提供了三个接口,支持单文件下载,多文件下载,多文件下载自定义命名。
15 |
16 | 1)单文件下载
17 |
18 | Downer("./file/test.txt");
19 |
20 | 2)多文件下载
21 |
22 | Downer(["./file/test.txt","./file/test.txt"]);
23 |
24 | 3)多文件下载自定义命名
25 |
26 | Downer({
27 | "1.txt":"./file/test.txt",
28 | "2.jpg":"./file/test.jpg"
29 | });
30 |
31 | 文件的 URL 如 `./file/test.jpg` 都可以改成 base64 或者其他格式,如:
32 |
33 | Downer({
34 | "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=="
35 | });
36 |
--------------------------------------------------------------------------------
/file/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/barretlee/javascript-multiple-download/fed09b290c84e354b63d9130f346b424696a21d0/file/test.jpg
--------------------------------------------------------------------------------
/file/test.rar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/barretlee/javascript-multiple-download/fed09b290c84e354b63d9130f346b424696a21d0/file/test.rar
--------------------------------------------------------------------------------
/file/test.txt:
--------------------------------------------------------------------------------
1 | test
--------------------------------------------------------------------------------
/lib.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Javascript 多文件下载
3 | * @author Barret Lee
4 | * @email barret.china@gmail.com
5 | */
6 | var Downer = (function(files){
7 | var h5Down = !/Trident|MSIE/.test(navigator.userAgent);
8 | // try{
9 | // h5Down = document.createElement("a").hasOwnProperty("download");
10 | // } catch(e){
11 | // h5Down = document.createElement("a").download;
12 | // }
13 |
14 | /**
15 | * 在支持 download 属性的情况下使用该方法进行单个文件下载
16 | * 目前 FF 还不支持 download 属性,所以 FF 必须另觅他法!
17 | * @param {String} fileName
18 | * @param {String|FileObject} contentOrPath
19 | * @return {Null}
20 | */
21 | function downloadFile(fileName, contentOrPath){
22 | var aLink = document.createElement("a"),
23 | evt = document.createEvent("HTMLEvents"),
24 | isData = contentOrPath.slice(0, 5) === "data:",
25 | isPath = contentOrPath.lastIndexOf(".") > -1;
26 |
27 | // 初始化点击事件
28 | // 注:initEvent 不加后两个参数在FF下会报错
29 | evt.initEvent("click",false,false);
30 |
31 | // 添加文件下载名
32 | aLink.download = fileName;
33 |
34 | // 如果是 path 或者 dataURL 直接赋值
35 | // 如果是 file 或者其他内容,使用 Blob 转换
36 | aLink.href = isPath || isData ? contentOrPath
37 | : URL.createObjectURL(new Blob([contentOrPath]));
38 |
39 | aLink.dispatchEvent(evt);
40 | }
41 |
42 | /**
43 | * [IEdownloadFile description]
44 | * @param {String} fileName
45 | * @param {String|FileObject} contentOrPath
46 | */
47 | function IEdownloadFile(fileName, contentOrPath, bool){
48 | var isImg = contentOrPath.slice(0, 10) === "data:image",
49 | ifr = document.createElement('iframe');
50 |
51 | ifr.style.display = 'none';
52 | ifr.src = contentOrPath;
53 |
54 | document.body.appendChild(ifr);
55 |
56 | // dataURL 的情况
57 | isImg && ifr.contentWindow.document.write("");
59 |
60 | // 保存页面 -> 保存文件
61 | // alert(ifr.contentWindow.document.body.innerHTML)
62 | if(bool){
63 | ifr.contentWindow.document.execCommand('SaveAs', false, fileName);
64 | document.body.removeChild(ifr);
65 | } else {
66 | setTimeout(function(){
67 | ifr.contentWindow.document.execCommand('SaveAs', false, fileName);
68 | document.body.removeChild(ifr);
69 | }, 0);
70 | }
71 | }
72 |
73 | /**
74 | * [parseURL description]
75 | * @param {String} str [description]
76 | * @return {String} [description]
77 | */
78 | function parseURL(str){
79 | return str.lastIndexOf("/") > -1 ? str.slice(str.lastIndexOf("/") + 1) : str;
80 | }
81 |
82 | return function(files){
83 | // 选择下载函数
84 | var downer = h5Down ? downloadFile : IEdownloadFile;
85 |
86 | // 判断类型,处理下载文件名
87 | if(files instanceof Array) {
88 | for(var i = 0, l = files.length; i < l ; i++)
89 | // bug 处理
90 | downer(parseURL(files[i]), files[i], true);
91 | } else if(typeof files === "string") {
92 | downer(parseURL(files), files);
93 | } else {
94 | // 对象
95 | for(var file in files) downer(file, files[file]);
96 | }
97 | }
98 |
99 | })();
100 |
--------------------------------------------------------------------------------
/test/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |