Pure front-end download pdf link files instead of opening a preview of the solution

Pure front-end download pdf link files instead of opening a preview of the solution

I. Introduction and demand

 1.1 Introduction

      XMLHttpRequest for exchanging data with the server in the background. This means that, for certain parts of the page to be updated without reloading the entire page.

      Question: Chrome will automatically call the built-in pdf reader opens

 1.2 Demand

      In Google (Chrome) browser, using a tag attribute download link to download pdf file, if it is the same domain, you can download; but if the field is different, instead of downloading, but open the page preview files directly. But demand is directly click to download the file, instead of opening a preview; and download the file stream returned backstage.

Second, download the file

2.1, ideas

    Download through a property tag, we can directly interface to download the data stream file returned back; therefore, if we can simulate send http requests to convert the file into a file link to use a flow label download download. Ideas and Methods The following describes the link to download the file stream file transfer

2.2, file transfer stream file path

1, first check whether the link is the path

Use regular expressions to check the legality url

. 1 the let REG = / ^ ([hH] [tT] {2} [pP]: \ / \ / | [hH] [tT] {2} [pP] [sS]: \ / \ /) (([A . -za-z0-9- ~] +)) + ([A-Za-z0-9- ~ \ /]) + $ / ;
 2   IF (! reg.test (URL)) {
 . 3      the throw  new new Error ( "parameter passed is not legitimate, not a standard link" );
 4   }

2, create XMLHttpRequest object

Analog transmission http request to obtain the file stream

. 1   the let XHR = new new XMLHttpRequest (); // Create XMLHttpRequest object 
2   xhr.open ( 'GET', 'HTTP: // URL', to true ); // type specifies requested, URL, and whether a request for asynchronous processing. Three parameters are method: the type of request; the GET or POST url: location of the file on the server async: true (asynchronous) or false (synchronous) 
. 3   xhr.setRequestHeader ( 'the Content-the Type', `file application / pdf`) ; // set request header
 . 4   xhr.responseType = "blob"; // data type of return needed here the blob 
. 5   xhr.onload = function () { // the request was successful callback 
. 6        IF ( the this .status == 200 is ) {
 7          // receiving binary stream 
. 8          var= BLOB the this .response;
 . 9        }
 10      }
 . 11   xhr.send (); // send a request to the server

3, complete method

1  / * *
 2  * turn file stream file link to download - pdf aimed to solve the problem Google browser to download a pdf label directly open
 3  * @param url: file link
 4  * @param fileName: file name;
 5  * @param type: file type;
 . 6   * / 
. 7  function fileLinkToStreamDownload (URL, fileName, type) {
 . 8    the let REG = / ^ ([hH] [tT] {2} [pP]: \ / \ / | [hH] [tT] {2} [pP] [sS ]: \ / \ /) (([A-Za-z0-9- ~] +)) + ([A-Za-z0-9- ~ \ /]) + $. / ;
 . 9    IF (! {reg.test (URL))
 10      the throw  new new Error ( "invalid parameters passed, is not a standard file link" );
 . 11    } the else {
 12 is      the let XHR =new XMLHttpRequest();
13     xhr.open('get', url, true);
14     xhr.setRequestHeader('Content-Type', `application/${type}`);
15     xhr.responseType = "blob";
16     xhr.onload = function () {
17       if (this.status == 200) {
18         //接受二进制文件流
19         var blob = this.response;
20         downloadExportFile(blob, fileName, type)
21       }
22     }
23     xhr.send();
24   }
25 }

 2.3, download the file

1, create a download link

. 1 the let downloadElement = document.createElement ( 'A' );
 2 the let the href = BLOB;
 . 3    IF ( typeof BLOB == 'String' ) {
 . 4      downloadElement.target = '_blank'; // if the link is, open a new tab Download 
. 5    } the else {
 . 6      the href = window.URL.createObjectURL (BLOB); // create the download link 
. 7    }
 . 8   downloadElement.href the href =; // download link

2, simulation click the download link

. 1 downloadElement.download tagFileName + = Moment ( new new a Date () the getTime ().) The format ( 'YYYYMMDDhhmmss') + + fileType. '.'; // the name of the file downloaded 
2  document.body.appendChild (downloadElement);
 . 3 downloadElement .click (); // Download

3, the download is complete release resources

. 1    document.body.removeChild (downloadElement); // download complete removal element 
2    IF ( typeof blob = 'String'! ) {
 . 3      window.URL.revokeObjectURL (the href); // relieve the blob 
4    }

4, complete method

1  / * *
 2  * download export file
 . 3  * @param blob: Returns the blob or linking data
 . 4  * @param tagFileName: after the download file name tag
 . 5  * @param fileType: File type word (docx) excel (xlsx) ppt and the like
 . 6   * / 
. 7  function downloadExportFile (BLOB, tagFileName, fileType) {
 . 8    the let downloadElement = document.createElement ( 'A' );
 . 9    the let the href = BLOB;
 10    IF ( typeof BLOB == 'String' ) {
 . 11      downloadElement.target = '_blank' ;
 12 is    } the else {
 13 is     = window.URL.createObjectURL the href (BLOB); // create a download link 
14    }
 15    downloadElement.href = the href;
 16    downloadElement.download tagFileName + = Moment ( new new .. a Date () the getTime ()) the format ( 'YYYYMMDDhhmmss' '.') + + fileType; // file name after downloading 
17    document.body.appendChild (downloadElement);
 18    downloadElement.click (); // Download 
19    document.body.removeChild (downloadElement); // download complete shift In addition to the elements 
20 is    IF ( typeof BLOB = 'String'! ) {
 21 is      window.URL.revokeObjectURL (the href);// relieve the blob 
22    }
 23 is  
24 }

 2.4, base64 object-file objects

Mainly for pictures, but other documents may also be

. 1  / * *
 2  * Base64 object-file objects
 . 3  * @param URLData: Base64 object data
 . 4  * @param type: Type Image / PNG;
 . 5  * @Returns} {Blob: Blob file object
 . 6   * / 
. 7  function base64ToBlob ( URLData, type) {
 . 8    the let urlData.split ARR = ( ',' );
 . 9    the let ARR = Array [0] .match (/:(.*?);/ )
 10    the let MIME = (Array && be array.length> ? Array. 1 [. 1]: type) || type;
 . 11    // remove url head, and transformed into byte 
12 is    the let bytes = window.atob (ARR [. 1 ]);
 13 is    // handle exceptions, less than the ascii code 0 conversion is more than 0 
14   ab & = the let new new an ArrayBuffer (bytes.length);
 15    // generate the view (for Direct Memory): 8-bit unsigned integer, a length byte 
16    the let IA = new new Uint8Array (ab &);
 . 17    for (I = 0 the let ; I <bytes.length; I ++ ) {
 18 is      IA [I] = bytes.charCodeAt (I);
 . 19    }
 20 is    return  new new Blob ([ab &], {
 21 is      type: MIME
 22 is    });
 23 is }

 2.5 Example

1. Download the file stream file transfer link

. 1 fileLinkToStreamDownload ( 'http://127.0.0.1/download.pdf', 'file download example', 'pdf')

2, base64 object-file objects to download

. 1 the let BLOB = base64ToBlob ( 'Data: Image / PNG; Base64, iVBORw0KGgo = ...', 'Image / PNG') // acquired image file stream 
2 downloadExportFile (BLOB, 'downloads', 'PNG')

  Record issues: the browser cache problem

  Because the browser's caching mechanism, when we use the XMLHttpRequest request, the browser will request the address of the cache address are compared, if it exists based on the same record request to the server and not directly back to the last time the same request content.

  Such caching problem solving approach:

1, the time stamp method - i.e. behind each request url string plus the current time, or other similar random string will not be repeated, so that every time that a browser is different url, as will be different i.e. to process the request, but does not read from the cache.

. 1   IF ( "?" Url.indexOf ()> = 0) { // determines whether the parameter has been url 
2          url = url + "T & =" + ( new new a Date ()) valueOf ();.
 . 3    } the else {
 . 4         URL URL + + = ( "T =?" new new a Date ()) valueOf ();.
 . 5        }

2, before sending a request XMLHttpRequest plus:

Add If-Modified-Since header

1 xhr.setRequestHeader("If-Modified-Since","0");  
2 xhr.send(null);

 

Guess you like

Origin www.cnblogs.com/jackson-yqj/p/11321275.html