File upload and download based on formdata and blob

Keywords: Javascript Attribute Session

First, introduce the basic knowledge used

formdata

Definition on MDN: the FormData interface provides a way to construct key value pairs that represent form data. After that, the data can be sent out using the XMLHttpRequest.send() method.
In short, it is the parameter used to construct http request (it can carry file data).

Common methods:
FormData(form)
Constructor, optional parameter, a form object Dom, will contain the value of the form
FormData.append(key,value)
Used to add a new attribute value. Even if the original attribute exists, it will not be overwritten, but a new key value pair
formdata.delete(key)
Used to delete object key value pairs

Example
html code

<form id="myForm" name="myForm">
  <div>
    <label for="username">Enter name:</label>
    <input type="text" id="username" name="username">
  </div>
  <div>
    <label for="useracc">Enter account number:</label>
    <input type="text" id="useracc" name="useracc">
  </div>
  <div>
    <label for="userfile">Upload file:</label>
    <input type="file" id="userfile" name="userfile">
  </div>
<input type="submit" value="Submit!">
</form>

js code

let form = document.getElementById('myForm');
let mrFormData = new FormData(form);
mrFormData.append('key1','value1');
mrFormData.append('key2','value2');

Blob

Blob is a js object used to construct stream type data
Constructor usage:
var aBlob = new Blob( array, options );
Where array is an array composed of binary data, string data, etc
options is an optional BlobPropertyBag dictionary,

Example

let aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; // An array containing DOMString
let oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // Get blob

With these two objects, you can start to upload and download files step by step

1. Generate a formdata object to transfer data to the server

 var mrFormData = new FormData();
 mrFormData.append("upload-type", "TYPE_MERGE");
 mrFormData.append("upload-name", 'XXXX');
 mrFormData.append("upload-total", 'XXXX');
 mrFormData.append("upload-index", 'XXXX');

2. Construct post request of ajax

var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        var result = xmlhttp.response;
        var header = xmlhttp.getResponseHeader("content-disposition");
        var fileName = getValueByStr('filename',header);
        transArray2Csv(result,fileName);//Generate csv
    }
}
xmlhttp.open("POST", url, true);
xmlhttp.setRequestHeader("X-Uni-Crsf-Token", (top.session && top.session.csrfToken) || "");
xmlhttp.responseType = "text";
xmlhttp.send(mrFormData);//Send data to server

3. Process the returned data to generate CSV and download

function transArray2Csv(result, filename) {
    var blob = new Blob([result], {
        type: "text/plain"
    })
    const link = document.createElement("a")
    link.href = URL.createObjectURL(blob)
    link.download = filename // Fill in the saved file name here
    link.click()
    URL.revokeObjectURL(link.href)
}

At this point, the download is complete

Precautions (problems encountered during development)
  1. The ajax function of jq does not support the processing of return stream data, so you need to write an ajax request yourself;
  2. When ajax requests post and sends data, it needs to add content type, xhr.setrequestheader ('content type ',' application / x-www-form-urlencoded ') in the header;
  3. When the sending data is formdata data, the browser will automatically identify and add the header content type: multipart / form data, and add a random string boundary to divide each attribute of formdata, and the background will parse formdata based on this;
  4. If there is no upload data, get request is the best way to download files;
  5. When js generates the file and downloads it, if there is an interface that can be directly used for file download, you can download the file by executing window.location.href = url, and the browser will not refresh, otherwise, use theDownload in tag mode.

Posted by grazzman on Wed, 06 Nov 2019 20:15:06 -0800