This is the third day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

What is Fetch?

  • The Fetch API provides an interface to Fetch resources
  • Request[1] was also standardized. And Reponse[2] objects

Fetch The process of downloading files

  1. Requests: Usually requests to download files are common GET and POST requests
  2. Response: The Response object of the Fetch API is the data of the Response, and the attributes used this time are
  • Response.headers[3] : Response header information used to get the name of the file
filename = decodeURIComponent(res.headers.get("content-disposition").replace("attachment; filename=".""));
Copy the code
  • Response.ok[4] : Boolean value, whether the Response is successful
If (res.ok){return res}else{// error handling}Copy the code
  • Response.body[5]ReadableStream: The content of the response[6]Type, bygetReader()[7]Method creates a ReadableStreamDefaultReader, read sequentially. After reading, you need to create a new ReadableStream that generates Response for passing the RES processing
const readStream = reader= > new ReadableStream({
    start(controller) {
        return push();
        function push() {
            return reader.read().then((res) = > {
                const { done, value } = res;
                if (done) {
                    controller.close();
                }
                controller.enqueue(value);
                returnpush(); }); }}});Copy the code
  • The generated ReadableStream is used to return a new Response for passing processing

The following method is equivalent to res.blob().

  • If res.blob() is available, use it as res.json(). Here is a case where res.blob() parsing occasionally fails
const resBlob = (reader, data, type) = > new Promise((resolve) = > {
    function push() {
        reader.read().then(({ done, value }) = > {
            data.push(value);
            done ? resolve(new Blob(data, { type })) : push();
        });
    }
    push();
});
Copy the code

4. Save the file

  • Read the bloB data with FileReader[8] and wait until the loadEnd event is complete to download it
  • reader.readAsText(blob): Starts reading the contents of the specified BLOB
const savingFile = (blob, fileName) = > {
    const reader = new FileReader();
    reader.addEventListener('loadend'.() = > downloadBlob(blob, fileName));
    reader.readAsText(blob);
};
Copy the code

Download files

  • Pass in the BLOB and file name for the download operation
const downloadBlob = (blob, fileName) = > {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.target = '_blank';
    a.style.display = 'none';
    document.body.appendChild(a);
    a.download = fileName;
    a.click();
    window.URL.revokeObjectURL(url);
    document.body.removeChild(a);
};
Copy the code

6. Examples

  • Set the parameters
    • Credentials: Indicates whether cookies are carried
    • Headers: What is the format of the request
const option = {
    credentials: 'include'.headers: new Headers({
        'Content-Type': 'application/x-www-form-urlencoded',})};/ / download
// Payload: Parameter of the fetch request
const download = (payload, filename = "Default file name. XLSX") = >
    fetch(`request/url?${qs.stringify(payload)}`, option)
        .then((res) = > {
            // Set the file name, obtained from the response header
            filename = decodeURIComponent(res.headers.get("content-disposition").replace("attachment; filename=".""));
            return new Response(readStream(res.body.getReader()));
        })
        .then((res) = >resBlob(res.body.getReader(), [], res.headers.get("Content-Type")))
        .then((response) = > savingFile(response, filename))
        .catch((error) = > message.warning(`${error.message}Please try again));
Copy the code

Vii. Reference documents

  1. Request
  2. Response
  3. Response.header
  4. Response.ok
  5. Response.body
  6. ReadableStream
  7. ReadableStream.getReader()
  8. FileReader