Enabling gzip compression with fetch.js

会有一股神秘感。 提交于 2021-02-07 13:14:15

问题


I'm using fetch.js (https://github.com/github/fetch) to send a relatively large json object to the backend. The json is large in that it include an SVG image string.

I'm not clear if fetch.js is using gzip compression by default, or if I need to manually compress and add headers. Any help would be appreciated.

return new Promise((resolve, reject) => {
  fetch(api_base + "/api/save-photo", {
    method: 'POST',
    mode: 'cors',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(payload)
  })
    .then((response) => {
      if (response.status === 404) {
        throw new Error('404 (Not Found)');
      } else {
        return response.json().then((json) => {
          console.log('save poster response: ', json);
          return json;
        });
      }
    });
});

回答1:


I'm assuming that with your line of

body: JSON.stringify(payload)

that payload isn't compressed.

I also wanted to be able to zip/compress a payload body and I also need an async approach to fit with the rest of my code. The bit I was struggling with was finding a way to use zlib without callbacks.

To achieve this, I did the following....

In a separate help library, I import zib...

import zlib from 'zlib'

I created the following functions....

async function asyncCompressBody(body) {

    const compressedData = await compressBody(body);
    console.log("Data Compressed");

    return compressedData;

}

function compressBody(body) {

    return new Promise( function( resolve, reject ) {

        zlib.deflate(body, (err, buffer) => {
            if(err){
                console.log("Error Zipping");
                reject(err);
            }

            console.log("Zipped");

            resolve(buffer);
        });
    });

}

The compressBody function is a promise around zlib.deflate. The function asyncCompressBody is an async function that allows the calling function to await.

In the calling function, I use it as...

let compressedBody = await asyncCompressBody(jsonContent);

let headers = new Headers();
headers.append("Content-Type","application/json");
headers.append("Content-Encoding","zlib");

const response = await fetch(url,
    {method: 'POST',
    headers:headers,
    body:compressedBody});



回答2:


Use https://github.com/nodeca/pako (a faster port of zlib).

Add the following import:

import { gzip } from 'pako';

Then, change:

body: JSON.stringify(payload)

To:

body: await gzip(JSON.stringify(payload))

And add the header:

'Content-Encoding': 'gzip',

Or, if you don't use the await/async syntax, your example code becomes:

return new Promise((resolve, reject) => {
  gzip(JSON.stringify(payload)).then((gzippedBody) => {
    fetch(api_base + "/api/save-photo", {
      method: 'POST',
      mode: 'cors',
      headers: {
        'Content-Encoding': 'gzip',
        'Content-Type': 'application/json'
      },
      body: gzippedBody
    })
      .then((response) => {
        if (response.status === 404) {
          throw new Error('404 (Not Found)');
        } else {
          return response.json().then((json) => {
            console.log('save poster response: ', json);
            return json;
          });
        }
      });
  });
});


来源:https://stackoverflow.com/questions/45943481/enabling-gzip-compression-with-fetch-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!