任何建议将不胜感激。 我的网络应用程序中有一个json变量,我想对其进行gzip压缩并通过预先签名的URL上传到S3。
我能够成功上传JSON,但是我无法对JSON进行gzip后再上传。
我尝试构建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 内容类型:“ application / x-gzip”和 内容编码:“ gzip”
但是,当文件(然后,如果经常出现网络错误)随后从S3下载时,当尝试在终端中使用gzip或gunzip解压缩时,会出现错误消息:“非gzip格式” >
我尝试遵循的来源:
https://github.com/nodeca/pako/issues/55 https://github.com/nodeca/pako/blob/master/examples/browser.html
答案 0 :(得分:0)
如果您期望有效负载在下载后仍保持压缩状态,则设置Content-Encoding: 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压缩的另一层中,并且希望浏览器删除外层,这实际上是您从未做过的。
答案 1 :(得分:0)
以下过程对我有用:
生成Content-Type:'application / json'的预签名URL。提供的文件名应在末尾包含.gz。在返回的预签名URL中,浏览URL应该验证内容类型为application / json。
因为我确定我的JSON不包含会中断到UTF-8转换的字符串,所以我执行以下操作(Angular中的代码,但它传达了结构):
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
代码中遵循的步骤:
然后您可以从S3下载压缩后的文件(浏览器应自动将其解压缩)并打开它以验证其是否包含相同的结果。