For the file download, can be said to be a very common topic, the front-end of many projects will have such a demand, such as the export of Highchart charts, online picture editing in the image preservation, online code editing code export and so on. And many times, we only give a link, the user needs to right click on the link, and then choose "Save as", this process is not troublesome, but still need two steps, if the user want to save the page of multiple linked files, you have to repeat the operation many times, the most common is the English listening website audio download, hand all points hemp!
The purpose of this article is to describe how to use JavaScript to download multiple files, that is, when a user clicks on a link or button, it also downloads several files simultaneously. Here "at the same time" is not very accurate, in the modern browser can implement multiple file parallel download, and in some older browsers, such as ie8-, this kind of browser can only be a single file download, but we can let a number of files in order to save, is a serial download it ~
Introduction to file types and their characteristics general types
Usually more common have txt, png, jpg, zip, tar and other file formats, these file formats, some browsers will directly open the link display content, while the other part, the browser does not recognize the response header, or can not parse the corresponding format, so as a file directly downloaded. Such as:
<a href= "Http://barretlee.github.io/test.rar" >file</a>
This code, if directly click the link, the browser will download the file directly.
Dataurl type
Dataurl is also a very common type that can be sent as a parameter to src or URL (). Some of the more common ones are as follows:
文本: data:text/plain;这里是正文内容。图片: data:image/jpg;base64,/9j/4AAQSkZJRgABAQEA.... data:image/png;base64,/9j/4AAQSkZJRgABAQEA....
Base64 is a relatively wide range of data formats.
Base64格式data:[][;charset=][;base64],Base64 在CSS中的使用:.demoImg{ background-image: url("data:image/jpg;base64,/9j/4QMZRXhpZgAASUkqAAgAAAAL...."); }Base64 在HTML中的使用:
Blob Stream
A Blob object represents an immutable class file object that contains the original data. Refer to the MDN documentation for specific content.
His use is also particularly convenient, such as:
var afileparts = [' <a id= ' a ' ><b id= ' b ' >hey!</b></a> ']; var New // The blob
Blob receives two parameters, one is an array type of data object, he can be ArrayBuffer, Arraybufferview, Blob, String and many other types; The second parameter is the MINE type setting. What we're going to use here is URLcreateObjectURL()
this function, whose role is to convert the content represented by a URL into a domstring, resulting in a file object or Blob object.
Binary stream
When we use the file API to read files, we get the binary stream format of the data, which can be received directly by ArrayBuffer and so on, which is not used in this article.
JavaScript Multi-File download
HTML5 a tag more than a property--download, the user click the link browser will open and display the content of the link, if the link is added download attribute, click on the link will not open this file, but directly download. Although relatively easy to use, but the low version of the browser is not compatible, this in the current 2 and 3 will talk about solutions.
Here, we can use the property detection to determine the browser type:
H5down = Document.createelement ("a"). hasOwnProperty ("Download");
The use of a label download property
With the download attribute, you can download individual files directly, and if you want to download multiple files at once, you have to deal with them:
1 function DownloadFile (fileName, content) { 2 Span style= "color: #0000ff;" >var aLink = document.createelement ("A" ), evt = document.createevent (" htmlevents " 5 evt.initevent (" click "); alink.download = FileName; alink.href = content; 9 10 }
The function of the download property, in addition to letting the browser ignore the MIME type of the file, also takes the value of the property as the file name. You can run this program from the Chrome console:
DownloadFile ("barretlee.html", "./");
The browser prompts you to keep (download) the HTML file. Before we mentioned that file types may also be dataurl or Blob streams, in order for the program to support these data types, slightly modify the following function:
1 functiondownloadFile (fileName, content) {2 varALink = document.createelement (' A ');3, blob =NewBlob ([content])4, evt = Document.createevent ("htmlevents");5 6Evt.initevent ("click");7 8Alink.download =FileName;9Alink.href =Url.createobjecturl (BLOB);Ten alink.dispatchevent (evt); One}
new Blob([content])
, the file is now converted into a Blog stream, and then used URL.createObjectURL()
to convert it to a domstring. This allows us to support the content of DATA64 and other data types ~
window.open after ExecCommand ("SaveAs")
Also mentioned above, although the download property is very convenient H5 weapon, but the low version of IE does not have the honor, to say the method, IE there are many ways to convert, such as ADOBE. The ActiveX object of stream can convert a file to a file stream and then write to a file to be saved. Here is a slightly more convenient way: first write the content into a new Window object, and then use ExecCommand to execute the Save command, it is equivalent to We press ctrl+s on the page, so that the information inside the page down.
1 // Open the file in a window and hide the window. 2var win = window.open ("Path/to/file.ext", "New Window", "width=0,height=0"); 3 // Press Ctrl+s in the win window to save the contents of the window 4 true, "filename.ext"); 5 // It's done, close the window. 6 win.close ();
This process is very clear, but there will be a problem, not the problem of the program, but the browser problem, if we use Sogou browser or 360 browser to open a new window, he will open a new tab, rather than open a new window, more hateful when some browsers do not allow window.open (This can be set). So he had to find another way.
Operation in IFRAME
Since the new window is so troublesome, I will finish the work in this window.
1 functioniedownloadfile (FileName, Contentorpath) {2 varIFR = document.createelement (' iframe ');3 4Ifr.style.display = ' None ';5IFR.SRC =Contentorpath;6 7 Document.body.appendChild (IFR);8 9 Ten //Save page, save file OneIfr.contentWindow.document.execCommand (' SaveAs ',false, fileName); A Document.body.removeChild (IFR); -}
General links We can add the SRC attribute directly to the IFRAME and then execute the saveAs command, what if we are using a data64 encoded file?
1 var isimg = Contentorpath.slice (0, ten) = = = "Data:image";23// Dataurl Case 45 contentorpath + "'/>");
This is also better handled, write the file directly into the IFRAME, and then save it in the execution.
The encapsulation of the code and the description of the interface code and the relevant DEMO
Package: Lib.js
Demo:javascript-multiple-download
The invocation of the interface
Provides three interfaces, supports single file download, multi-file download, multi-file download custom naming.
1) Single File download
Downer ("./file/test.txt");
2) Multi-File download
Downer (["./file/test.txt", "./file/test.txt"]);
3) Multi-file download custom naming
Downer ({ "1.txt": "./file/test.txt", "2.jpg": "./file/test.jpg"});
The URL of the file ./file/test.txt
can be changed to base64 or other format.
Server support and backend implementation for back-end implementation
The back-end implementation of the principle is to add some special tags in the response header, such as the front-end to send such a request:
function Download (path) { var ifrm = document.getElementById (frame); = "Download.php?path=" +path;}
The back-end response is
<? php Header ("Content-type:application/octet-stream"); Header ("content-disposition:attachment; Filename= ". $_get[' path '); ReadFile ($_get[' path ');? >
Tell the browser that this is a stream file that is sent to you as an attachment, please ignore MINE type and save directly.
Server Configuration
If the background is apche as the server, you can configure the htaccess file:
<filesmatch "\. (Zip|rar) $ "=" ">Header set Content-disposition attachment</filesmatch>
This means that as long as the request is a zip or rar file type, so long add a Content-Disposition:attachment
response header. This allows you to omit troublesome operations from the PHP code.
Summary
Due to the hasty text, there will be a lot of errors in the paper, there is a better proposal for a multi-file download, hope to share together!
Resources
- Create and download files with JS on the browser side Alloyteam
- Starting file download with Javascript Ahzaz ' s Blog
- Blob Stream MDN
JavaScript multi-File download