Example of front end javascript to realize file download

  • 2021-09-24 21:20:20
  • OfStack

In html5, the download attribute is added to the a tag. When the link containing this attribute is clicked, the browser will download the link on the href attribute as a download file. Example:


<a href="https://www.baidu.com" rel="external nofollow" download="baidu.html"> Download </a>

1. Implementation and example of front-end js download

By dynamically creating an a element containing download attributes through javascript, and then triggering a click event, the front-end download can be realized.

Code example:


function download(href, title) {
    const a = document.createElement('a');
    a.setAttribute('href', href);
    a.setAttribute('download', title);
    a.click();
}

Description:

The href property sets the address of the file to download. This address supports multiple formats, so rich download methods can be realized. The download property sets the name of the downloaded file. However, when the href property is a normal link and cross-domain, this property value setting is mostly ignored by browsers.

1.1 Normal Connection Download Sample


//  Download pictures 
download('https://lzw.me/images/gravatar.gif', 'lzwme-gravatar');
//  Download 1 Connections 
download('https://lzw.me', 'lzwme-index.html');

1.2 href is an example of data URIs
data URI is an URL prefixed data: scheme that allows content creators to embed small files in documents. The data URI consists of four parts: the prefix (data:), the MIME type indicating the data type, the optional base64 token if it is not text, and the data itself:


data:[<mediatype>][;base64],<data>

When the href attribute of the link is data URIs, the file content can also be downloaded. Example:


download('data:,Hello%2C%20World!', 'data-uris.txt');
download('data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D', 'data-uris.txt');

1.3 canvas Download Sample
For canvas, the content in data URIs format can be obtained by toDataURL method.

1.4 Binary Content Download
The URL. createObjectURL method creates an URL pointing to the parameter object based on the parameter passed in. The new object URL points to the executing File object or Blob object.

The parameters of URL. createObjectURL are File objects or Blob objects, File objects are files selected through input [type=file], and Blob objects are binary data.

Set the return value of URL. createObjectURL to the value of href attribute, and you can download binary content. Example:


const content = 'Welcome to lzw.me!';
const blob = new Blob([content]);
const href = URL.createObjectURL(blob);
download(href, 'download-text.txt');
URL.revokeObjectURL(href);

1.5 Example of front-end download method
Based on the above discussion, here is an TypeScript example of the saveAs method for front-end implementation download:


/**
 *  By creating  a dom  Downloading front-end files by object mode 
 * @param href  Link to the content to download. When defined  toBlob  Can be plain text or 2 Binary data ( Depend on  toBlob  Format 
 * @param fileName  The name of the downloaded file 
 * @param toBlob  If this parameter is set, the  blob  The mode will  href  To the contents of the file to save, this parameter will be entered as  new Blob([href], toBlob)  The first part of 2 Parameters 
 * @example
 * ```js
 * saveAs('abc', 'abc.txt', {});
 * saveAs('data:,Hello%2C%20World!', 'hello.txt');
 * saveAs('https://lzw.me/images/avatar/lzwme-80x80.png', 'lzwme-logo.png');
 * ```
 */
export function saveAs(href: string | Blob, fileName?: string, toBlob?: PlainObject) {
 const isBlob = href instanceof Blob || toBlob;
 if (!fileName && typeof href === 'string' && href.startsWith('http')) {
  fileName = href.slice(href.lastIndexOf('/') + 1);
 }
 fileName = decodeURIComponent(fileName || 'download');
 if (typeof href === 'string' && toBlob) href = new Blob([href], toBlob);
 if (href instanceof Blob) href = URL.createObjectURL(href);
 const aLink = document.createElement('a');
 aLink.setAttribute('href', href);
 aLink.setAttribute('download', fileName);
 aLink.click();
 // const evt = document.createEvent("HTMLEvents");
 // evt.initEvent("click", false, false);
 // aLink.dispatchEvent(evt);
 if (isBlob) setTimeout(() => URL.revokeObjectURL(aLink.href), 100);
 return aLink;
}

2. Detect whether the browser supports the download property

The download attribute is the new content of html5. For browser support, please refer to: http://caniuse.com/# feat=download

< img src="https://lzw.me/wp-content/uploads/2017/04/a-download.png" alt="" width="879" height="346" class="aligncenter size-full wp-image-2330" / >

To determine whether the browser supports this attribute, you only need to check whether the download attribute exists in the a tag. Example:


const downloadAble = 'download' in document.createElement('a');

For unsupported browsers, we can only think of other ways or downgrade them.

3. Implementation using the serviceWorker and fetch API proxies

There is more demand for front-end downloads because content comes from the front end. Then one such API can be implemented at the back end, which returns data in download format after receiving the content sent by the front end. There is no browser compatibility problem in this implementation.

Using serviceWorker and fetch API to intercept browser requests, this functional requirement can be realized only by implementing the convention logic. Example:

In the page, construct the request through fetch API:


fetch('lzwme.txt', {
    isDownload: true,
    body: {
        data: new Blob('hi!')
    }
})

In serviceWorker, a request with isDownload header information is intercepted and a download response is constructed:


self.addEventListener('fetch', function(event) {
    const req = event.request;
    if (!req.headers.get('isDownload')) {
        retrun fetch(req);
    }
    const filename = encodeURIComponent(req.url);
    const contentType = req.headers.get('Content-Type') || 'application/force-download';
    const disposition = "inline;filename=" + filename + ";filename*=utf-8''" + filename
    const myBody = req.headers.get(body).data;
    event.respondWith(
        new Response(myBody, {
            headers: {
                'Content-Type': contentType,
                'Content-Disposition': disposition
            }
        })
    );
});

4 Download server files using ajax (xhr vs. fetch API)

What is mainly discussed above is the method of downloading and saving files with pure front-end. For downloading server files, the simplest way is window. open (url) and location. href=url, but its disadvantages are also obvious. When something goes wrong, the whole page will hang up, and the download status and progress cannot be obtained. When the download time is a little longer, the experience is rather bad.

The following describes the method of downloading files using xhr and fetch and API under 1. The main idea is: set the request result to Blob type, and then use the front-end download to save Blob type data to realize download.

4.1 Downloading Remote Server Files Using xhr
Code example:


function download(href, title) {
    const a = document.createElement('a');
    a.setAttribute('href', href);
    a.setAttribute('download', title);
    a.click();
}
0

Download remote server files using fecth API


function download(href, title) {
    const a = document.createElement('a');
    a.setAttribute('href', href);
    a.setAttribute('download', title);
    a.click();
}
1

The above is the front-end javascript implementation of the details of the file download example, more information about the JavaScript file download please pay attention to other related articles on this site!


Related articles: