1. Invoke the back-end interface to export files

Sample download interface URL https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-assets/extension/0.3.9/package.crx~tplv-t2oaga2asx-image.image

1.1 window.open(url)

A new window opens and closes automatically when the download begins. Safair does not close the new window after downloading. Chrome, IE and Safair support it, but firefox does not

1.2 window.location=url

Download in the current window

Chrome, Safair support

1.3 iframe

function downloadByIframe (url) {
    try {
        const iframe = document.createElement('iframe');
        iframe.src = url;
        iframe.style.display = 'none';
        document.body.appendChild(iframe);
    } catch (e) {
        
    }
}
Copy the code
<button onclick="downloadByIframe(url)">download</button>
Copy the code

In HTML, the iframe attribute is SRC, but in JS, only some browsers support SRC modification (read ok), the real generic is to modify the href value of the corresponding frame.

function changeIframeSrc (url) {
    window.iframes['myIframe'].location.href = url;
}
Copy the code

1.4 <a href="url" download="filename">

function downloadByAElement (url, fileName) {
    try {
        const element = document.createElement('a');
        element.href = url;
        element.download = fileName;
        const a = document.body.appendChild(element);
        a.click();
        document.body.removeChild(element);
    } catch (e) {
        
    }
}
downloadByAElement ('https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-assets/extension/0.3.9/package.crx~tplv-t2oaga2asx-image.image'.'test');
Copy the code

HTML5 has added a download attribute to the A tag. As long as there is this attribute, when clicking the link, the browser will not open the file pointed to by the link, but download it. Currently, only Chrome, Firefox, Opera and Edge support this attribute. This method is often used to click download picture. IE does not support the download attribute of a tag or allow JS to call the click method of a tag.

2. The front-end directly exports files to the local PC

2.1 Convert data to DataURI for use<a>Download the label

<a href="DataURI" download="filename">

function saveData2File (data, fileName) {
    try {
        const element = document.createElement('a');
        cosnt uri = getDownloadUri(data);
        element.href = uri;
        element.download = fileName;
        const a = document.body.appendChild(element);
        cosnt evt = document.createEvent('HTMLEvents');
        evt.initEvent('click'.false.false); Firefox displays an error without adding the following two parameters
        a.dispatchEvent(evt);
        document.body.removeChild(element);
    } catch (e) {
        
    }
}
Copy the code

Note: The browser has a limit on the href URL length. Exceeding this limit will result in a download failure.

The browser Maximum length (number of characters) note
IE 2083 If this number is exceeded, the submit button does not respond
Firefox 65536
Chrome 8182
Safari 80000
Opera 190000

Data URI Scheme

A Data URI Scheme is a class of URIs that can include images in a Web page without requiring any additional HTTP requests. Data URI schemes are commonly used to embed Base64-encoded Data in web pages to reduce the number of links to requested resources. Previous versions of Internet Explorer 8 did not support data URI schemes.

DataURIThe format of:

data: [<mime-type>][;charset=<charset>] [;<encoding>].<encoded data>
Copy the code
  • data:The name of the protocol
  • [<mime-type>]Optional, data type, commonly usedimage/png.image/svg+xml.text/plain
  • [;charset=<charset>]Optional character set encoding for the source text.[<mime type>][;charset=<charset>]The default value is the content-type field of the HTTP Header.
  • [;<encoding>]Data encoding (US-ASCII, BASE64), the default value is US-ASCII, that is, each character will be encoded as %xx
  • ,<encoded data>Encoded data, if<encoded data>Not in[;<encoding>]Data encoded in the

generateDataURIThe way of

1. encodeURIComponent
function getDownloadUri (data) {
    const mimeType = 'attachment/csv';
    const charset = '; charset=utf-8,';
    const _utf = '\uFEFF'; // In order to make the file in UTF-8 encoding mode, but also to solve the problem of Chinese garble
    return 'data:' + mimeType + charset + _utf + encodeURIComponent(data)
}
Copy the code

With this approach, URI lengths tend to exceed browser limits when there is too much data. EncodeURIComponent is commonly used to transcode interface parameters. In order to prevent the server from receiving unexpected requests, encodeURIComponent should be used to escape any content entered by the user as part of the URI.

2. URL.createObjectURL

Url. createObjectURL takes either a File object or a Blob object

  • FileThe object is just passinginput[type=file]Selected file
  • A Blob object represents an immutable, raw data-like file object

URL. CreateObjectURL is not supported below Internet Explorer 10

function getDownloadUri (data) {
    const _utf = '\uFEFF'; // In order to make the file in UTF-8 encoding mode, but also to solve the problem of Chinese garble
    if (window.Blob && window.URL && window.URL.createObjectURL) {
        const blob = new Blob([_utf + data], {
            type: 'text/json' // Write your own data format
        });
        returnURL.createObjectURL(blob); }}Copy the code

2.2 windows.navigator.msSaveBlobIe 10 ~ special Edge

MsSaveBlob is an IE10~Edge private method.

function downloadByMsSaveBlob (data) {
    const _utf = '\uFEFF'; // In order to make the file in UTF-8 encoding mode, but also to solve the problem of Chinese garble
    const blob = new Blob([_utf + data], {
        type: 'text/json' // The format of the data you need
    });
    navigator.msSaveBlob(_csvData, fileName); 
}
Copy the code

2.3 execCommand

When an HTML document switches to design mode, the document exposes the execCommand method, which allows commands to be run to manipulate elements in the editable content area.

Some sources have mentioned that IE9 can use execCommand method to save data to local files, but I have not verified it myself, so I don’t know if it is feasible. Moreover, the SaveAs command is not found in the MDN file execCommand. This is just a little note.

function saveFileByExecCommand (data, fileName) {
    const newWindow = window.top.open('about:blank'.'_blank');
    newWindow.document.write('sep=,\r\n' + data);
    newWindow.document.close();
    newWindow.document.execCommand('SaveAs'.false, fileName);
    newWindow.close();
}
Copy the code

Js data directly export/download data to local to method summary


function saveData2File (data, fileName) {
    const bw = getBrowser(); // Get browser information
    if(! bw['edge') | |! bw['ie']) {
        const element = document.createElement('a');
        cosnt uri = getDownloadUri(data);
        element.href = uri;
        element.download = fileName;
        const a = document.body.appendChild(element);
        cosnt evt = document.createEvent('HTMLEvents');
        evt.initEvent('click'.false.false); Firefox displays an error without adding the following two parameters
        a.dispatchEvent(evt);
        document.body.removeChild(element);
    } else if (bw['ie'] > =10 || bw['edge'= = ='edge') {
      const _utf = '\uFEFF'; // In order to make the file in UTF-8 encoding mode, but also to solve the problem of Chinese garble
      const blob = new Blob([_utf + data], {
        type: 'text/json' // The format of the data you need}); navigator.msSaveBlob(blob, fileName); }}function getBrowser () {
    const sys = {};
    const ua = navigator.userAgent.toLowerCase();
    if (ua.indexOf('edge')! = =- 1) {
      sys.edge = 'edge';
    } else if (ua.match(/rv:([\d.]+)\) like gecko/)) {
      sys.ie = ua.match(/rv:([\d.]+)\) like gecko/) [1];
    } else if (ua.match(/msie ([\d.]+)/)) {
      sys.ie = ua.match(/msie ([\d.]+)/) [1];
    } else if (ua.match(/firefox\/([\d.]+)/)) {
      sys.firefox = ua.match(/firefox\/([\d.]+)/) [1];
    } else if (ua.match(/chrome\/([\d.]+)/)) {
      sys.chrome = ua.match(/chrome\/([\d.]+)/) [1];
    } else if (ua.match(/opera.([\d.]+)/)) {
      sys.opera = ua.match(/opera.([\d.]+)/) [1];
    } else if (ua.match(/version\/([\d.]+).*safari/)) {
      sys.safari = ua.match(/version\/([\d.]+).*safari/) [1];
    }
    return sys;
  }

Copy the code

References:

  • Segmentfault.com/a/119000001…
  • www.cnblogs.com/xieshuxin/p…
  • www.cnblogs.com/wteng/p/574…