浏览器Javascript:将Json压缩到gzip并上传到S3预签名URL

浏览器Javascript:将Json压缩到gzip并上传到S3预签名URL,javascript,amazon-s3,gzip,pako,Javascript,Amazon S3,Gzip,Pako,如有任何建议,将不胜感激。 我在我的web应用程序中有一个json变量,我想通过预先指定的URL将其gzip并上传到S3 我能够成功地上传JSON,但我无法gzip JSON然后上传它 我尝试用三种不同的方式构建gzip json: // example json const someJson = { testOne: 'a', testTwo: 'b' }; // Attempt one const stringUtf16 = JSON.stringify(someJson); const

如有任何建议,将不胜感激。 我在我的web应用程序中有一个json变量,我想通过预先指定的URL将其gzip并上传到S3

我能够成功地上传JSON,但我无法gzip JSON然后上传它

我尝试用三种不同的方式构建gzip json:

// example json
const someJson = { testOne: 'a', testTwo: 'b' };

// Attempt one
const stringUtf16 = JSON.stringify(someJson);
const resultAsBinString = pako.gzip(stringUtf16);

// Attempt two
const stringUtf16 = JSON.stringify(someJson);
const resultAsBinString = pako.gzip(stringUtf16, { to: 'string' });

// Attempt three
const stringUtf16ThatWeNeedInUtf8 = JSON.stringify(someJson);
const stringUtf8 = unescape(encodeURIComponent(stringUtf16ThatWeNeedInUtf8));
const resultAsBinString = pako.gzip(stringUtf8);
对于每一次尝试,我都通过Angular的HTTP客户端上传resultAsBinString,其中包含头文件 内容类型:“应用程序/x-gzip”和 内容编码:“gzip”

但是,当(如果经常出现网络错误)文件随后从S3下载时,当尝试在终端中使用gzip或gunzip解压时,会给出一条错误消息:“不是gzip格式”

我试图追踪的消息来源:


设置
内容编码:gzip
不正确,如果您希望负载在下载后保持gzip。这仅在您希望浏览器透明地解码gzip编码时使用,例如在提供gzip HTML、JavaScript、CSS等时

如果使用了
Content Encoding:gzip
,则应将
Content-Type
设置为与实际负载匹配,例如
Content-Type:application/json

如果使用了
Content-Type:application/x-gzip
,则不应使用
Content-Encoding
,除非您使用不同种类的压缩来重新压缩gzip负载(不太可能)


Content-Type:application/x-gzip
Content-Encoding:gzip
相结合意味着您已经将一个gzip文件包装在另一层gzip压缩中,并且希望浏览器删除外层,这在实践中是不可能的。

以下过程对我有效:

生成内容类型为“application/json”的预签名URL。提供的文件名末尾应包含.gz。在返回的预签名URL中,扫描URL应验证内容类型为application/json

因为我确信我的JSON不包含任何会破坏到UTF-8转换的字符串,所以我会执行以下操作(以角度编码,但它会传递结构):

代码中遵循的步骤:

  • 内容类型头是application/json,内容编码是gzip
  • 将JSON字符串化
  • 将字符串转换为UTF-8
  • Gzip字符串
  • 从压缩的数据创建一个文件
  • 将文件上载到预先签名的URL

  • 然后,您可以从S3下载gzip文件(浏览器应自动解压缩),并打开它以验证它是否包含相同的结果。

    谢谢您的回答。这是问题的一部分。
    const headers = new HttpHeaders({
        'Content-Type': 'application/json',
        'Content-Encoding': 'gzip'
    });  //1
    const httpOptions = {
        headers: headers
    };
    const str = JSON.stringify(geoJson); //2
    const utf8Data = unescape(encodeURIComponent(str)); //3
    const geoJsonGz = pako.gzip(utf8Data); //4
    const gzippedBlob = new Blob([geoJsonGz]); //5
    upload = this.httpClient.put(presignedUploadUrl, gzippedBlob, httpOptions); //6