Amazon S3静态文件的GZIP压缩

28

我希望在我的网站上实现GZIP压缩。我已经在IIS上实现了它,HTML页面成功压缩,如预期所示。

现在问题出在CSS和JS文件上,这些文件是从Amazon S3获取的,它们完全没有被压缩。我也想压缩它们。

请指导我如何操作。分享相关链接将对我有很大帮助。

更新:我在S3文件上添加了Meta Header "Content-Encoding:gzip",现在在响应头中它显示出来了。但文件大小仍然相同,在页面中没有特定CSS的效果,甚至无法在浏览器中打开它。这是特定css的[链接][1]。

谢谢

3个回答

24

谢谢John,我明白了。如果您有在Windows中压缩CSS和JS文件的链接,能否请您分享给我? - RaJesh RiJo
1
只需搜索“Windows gzip”,您就可以找到一些压缩实用程序。 - John Rotenstein
1
@RaJeshRiJo 我建议在Windows上使用7zip http://www.7-zip.org/download.html - Virgil Shelton
2
此解决方案已过期。自2015年12月起,Cloudfront现在可以在传输文件时进行压缩。详见:http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html。 - J_A_X
2
除非您向存储桶添加CORS配置以公开Content-Length标头,否则Cloudfront不会压缩S3文件。请参阅http://ithoughthecamewithyou.com/post/enable-gzip-compression-for-amazon-s3-hosted-website-in-cloudfront了解详细信息。 - Robert Ellison
显示剩余2条评论

14
如果您在S3桶前面使用了CloudFront,则无需手动压缩HTML资源(CloudFront将实时对其进行压缩)。请注意,CloudFront仅以gzip格式压缩(不支持deflate、brotli),并且仅根据内容类型压缩CSS / JS / HTML。详见https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types。要使其正常工作,您需要将一些HTTP标头从CloudFront转发到S3(请参阅文档)。
如果您的S3存储桶包含CloudFront不支持的资源(通用的“二进制/octet-stream”MIME类型,例如“hdr”纹理或“nds” ROM),则需要在上传到S3之前自行压缩它们,然后设置资源上的“content-encoding”HTTP元标记。请注意,只有支持gz编码的浏览器才能下载并解压文件。
如果您不想逐个手动压缩文件,则可以使用Lambda函数:
- 每个PUT操作(即上传到桶中的文件)都会触发该函数。 - 如果文件尚未压缩且压缩有用,则替换原始上传文件为已压缩版本。 - 设置HTTP标头content-encoding为gzip。

我为此编写了一个GIST,它可以启发你创建自己的过程。请参见https://gist.github.com/psa-jforestier/1c74330df8e0d1fd6028e75e210e5042

别忘了使Cloudfront失效(清除),以应用你的更改。


.json文件算作JS吗? - JeanAlesi
快速更新和澄清 - CloudFront 现在支持并优先使用 brotli 而非 gzip。它还可以压缩更多的内容,不仅限于 html、css、js... 只要文件大小在 1MB 到 10MB 之间(当我上传一个 20MB 的 geojson 文件时发现它没有被压缩,所以我必须在上传前进行压缩)。 - misteraidan
以下是文件类型(按内容类型标头)的相关信息:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types - misteraidan
1
不要在CloudFront上使用此功能。原因:只有当CPU可用时,CloudFront才会压缩资源。听起来很好,对吗?错了。如果请求文件时CPU不可用,则会提供未压缩的文件并将其缓存,直到过期或由于缺乏访问而过期。经验证实,这种情况经常发生-通过web.dev/measure进行的随机测试将显示出来。 - huntharo

1
如果您只想压缩S3存储桶中现有的文件,则可以编写一个Lambda函数。将文件读入缓冲区,然后使用gzip库对其进行压缩并重新上传到S3。类似于如下内容应该可以工作:
 gzipped_content = gzip.compress(f_in.read())
                destinationbucket.upload_fileobj(io.BytesIO(gzipped_content),
                                                        final_file_path,
                                                        ExtraArgs={"ContentType": "text/plain"}
                                                )

这里有一份完整的教程:https://medium.com/p/f7bccf0099c9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接