浏览器Javascript:将Json压缩到gzip并上传到S3预签名URL
如有任何建议,将不胜感激。 我在我的web应用程序中有一个json变量,我想通过预先指定的URL将其gzip并上传到S3 我能够成功地上传JSON,但我无法gzip JSON然后上传它 我尝试用三种不同的方式构建gzip json:浏览器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
// 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转换的字符串,所以我会执行以下操作(以角度编码,但它会传递结构):
代码中遵循的步骤:
然后,您可以从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