自动为整个 S3 bucket 设置缓存控制(使用 bucket 策略?)

我需要为整个 s3存储桶设置缓存控制头,包括现有的和未来的文件,并希望在一个存储桶策略中这样做。 我知道我可以编辑现有的文件,如果我自己上传它们,我知道如何在 put 上指定它们,但不幸的是,上传它们的应用程序不能设置标题,因为它使用 s3fs 来复制那里的文件。

114229 次浏览

我不认为您可以在桶级别指定这个,但是有一些变通方法可供您使用。

  1. 在 S3上将对象复制到它自己 ,为复制操作设置适当的 cache-control标头。

  2. 在文件 的 URL 中指定响应头。您需要使用预先签名的 url 来实现这一点,但是您可以在查询字符串中指定某些响应头,包括 cache-controlexpires。有关可用选项的完整列表,请参阅: < a href = “ http://docs.amazonwebservices.com/amazons3/update/API/RESTObjectGET.html? r = 5225”rel = “ noReferrer”> http://docs.amazonwebservices.com/amazons3/latest/api/restobjectget.html?r=5225

现在有3种方法可以做到这一点: 通过 AWS 控制台通过命令行通过 s3cmd 命令行工具


AWS 控制台说明

这是现在推荐的解决方案。它是直截了当的,但它可能需要一些时间。

  • 登录到 AWS 管理控制台
  • 进入 S3桶
  • 按路由选择所有文件
  • 从菜单中选择“更多”
  • 选择“更改元数据”
  • 在“键”字段中,从下拉菜单中选择“ Cache-Control” Max-age = 604800为 Value 输入(7天)
  • 按“保存”按钮

(感谢@biplob-请在下面给他一些爱)


命令行解决方案

最初,当我创建这个 bucket 策略时是不可行的,所以我想到了如何使用 awscli 来实现它,它非常灵活。在研究的时候,我在野外找不到任何例子,所以我想我可以发布一些我的解决方案来帮助那些需要帮助的人。

注意: 默认情况下,aws-cli 只复制文件的当前元数据,即使您指定了新的元数据。

要使用在命令行上指定的元数据,需要添加“—— meta-DirectionREPLACE”标志。这里有一些例子。

就为了一个文件

aws s3 cp s3://mybucket/file.txt s3://mybucket/file.txt --metadata-directive REPLACE \
--expires 2034-01-01T00:00:00Z --acl public-read --cache-control max-age=2592000,public

对于整个 bucket (注意——递归标志) :

aws s3 cp s3://mybucket/ s3://mybucket/ --recursive --metadata-directive REPLACE \
--expires 2034-01-01T00:00:00Z --acl public-read --cache-control max-age=2592000,public

我发现了一个小问题,如果你只想把它应用到一个特定的文件类型,你需要排除所有的文件,然后包括那些你想要的。

只有 jpgs 和 png:

aws s3 cp s3://mybucket/ s3://mybucket/ --exclude "*" --include "*.jpg" --include "*.png" \
--recursive --metadata-directive REPLACE --expires 2034-01-01T00:00:00Z --acl public-read \
--cache-control max-age=2592000,public

如果你需要更多信息,这里有一些手册的链接:

已知问题:

"Unknown options: --metadata-directive, REPLACE"

这可能是由于过时的原因-见 @ eliotRosewater 的回答如下


S3cmd 工具

S3cmd 是一个“用于管理 AmazonS3和 CloudFront 服务的命令行工具”。虽然这个解决方案需要一个 git pull,但它可能是一个更简单、更全面的解决方案。

完整的指示,见下面@ashishyadaveee11的帖子


希望能有帮助!

步骤

  1. git clone https://github.com/s3tools/s3cmd
  2. 运行 s3cmd --configure (你会被要求两个键-复制和粘贴他们从您的 确认电子邮件或从您的亚马逊帐户页面。小心时 复制它们! 它们是区分大小写的,必须准确输入 否则你会不断得到关于无效签名或类似的错误。 请记住向密钥添加 s3:ListAllMyBuckets权限,否则在测试访问权限时将得到 AccessDenied错误。)
  3. ./s3cmd --recursive modify --add-header="Cache-Control:public ,max-age= 31536000" s3://your_bucket_name/

对于那些试图使用丹的答案并得到错误答案的人:

“未知选项: —— meta-direct,REPLACE”

我遇到了这个问题,问题是我安装 awscli 时使用了

Sudo apt-get install awscli

这样就安装了一个旧版本的 awscli,该版本缺少—— meta-direct 命令。所以我使用 sudo apt-get remove awscli 来删除它。

然后按照亚马逊的程序重新安装: Http://docs.aws.amazon.com/streams/latest/dev/kinesis-tutorial-cli-installation.html

唯一的区别是,我必须使用 sudo-H,因为其他人也可能会遇到权限问题。

您总是可以在 S3上的 PUTOBJECT 上配置一个 lambda 触发器,lambda 将简单地更改刚放置的这个特定对象的头部。

然后您可以最后一次运行上面提到的 copy 命令,并且所有的新对象都将由 lambda 修复。

更新:

这是一个很好的起点: https://www.aaronfagan.ca/blog/2017/how-to-configure-aws-lambda-to-automatically-set-cache-control-headers-on-s3-objects/

现在,可以从 AWS 控制台轻松地更改它。

  • 登录到 AWS 管理控制台
  • 进入 S3桶
  • 按路由选择所有文件
  • 从菜单中选择“更多”
  • 选择“更改元数据”
  • 在“键”字段中,从下拉菜单中选择“ Cache-Control”
  • Max-age = 604800为 Value 输入(7天)
  • 按“保存”按钮

执行所需的时间取决于您的 bucket 文件。 如果不小心关闭了浏览器,请从头重做。

这个问题我已经研究了一段时间了。直到我发现和阅读的文件。在这里分享一下,以防对其他人有帮助:

这个命令最终可靠地为我工作。为了验证预期的结果,我选择了1秒的过期时间:

aws s3 cp \
--metadata-directive REPLACE \
--cache-control max-age=1,s-maxage=1 \
s3://bucket/path/file \
s3://bucket/path/file
  • 当“ cp”修改 S3中现有文件的元数据时,需要使用 --metadata-directive REPLACE
  • max-age设置浏览器缓存时间(以秒为单位)
  • s-maxage设置 CloudFront 缓存,以秒为单位

同样,如果在上传到 S3时在文件上设置这些 Cache-Control头值,则命令将类似于:

aws s3 cp \
--cache-control max-age=1,s-maxage=1 \
/local/path/file \
s3://bucket/path/file

存储桶策略是为存储在其中的存储桶和对象授予权限,所以这条路不会产生您所寻找的结果。其他答案使用自动方法修改对象元数据,但是如果愿意将桶移到 CloudFront 后面,也可以使用 Lambda@Edge。

使用 Lambda@Edge,您可以为每个客户端请求运行任意代码,并且它可以更改从原点返回的头(本例中为 S3 bucket)。它需要更多的配置,并且需要花费一些钱,但是这里有一个解决方案的蓝图:

  • 创建 CloudFront 发行版
  • 加上 S3桶作为原点
  • 创建一个修改响应头的 lambda 函数
  • 使用 CloudFront 发行版的 URL 访问文件

AWS 文档中有如何修改响应头的 一个例子。如果您碰巧使用 Terraform 来管理基础设施,我已经编写了 一篇文章如何做到这一点。

以前的答案要么与问题本身不相符,要么就要付出代价(Lambda)。

您应该做的是在上传文件时设置“ cache-control”头(PutObject 或 MultiPartUpload)。

根据您的语言,它可能有些不同。文档不是很清楚(可能 AWS 希望您用其他解决方案支付这些费用)。

PHP 的一个例子:

$uploader = new MultipartUploader ($s3,$filename,[
...,
'before_initiate' => function(\Aws\Command $command){
$command['CacheControl'] = 'max-age=31536000,public';
},
...
]);

围棋的另一个例子:

cc := "max-age=31536000,public"
input := &s3.PutObjectInput{
...,
CacheControl: &cc,
}

因为之前的答案误导了我,所以我想我应该和大家分享一下我的用法:

aws s3 cp s3://bucketname/ s3://bucketname/ --cache-control max-age=12345 --recursive

对于已经存在的内容,使用 CP。像这样设置 --cache-control是一个有效的选项。

如果你正在上传,你也可以使用 同步,其命令是:

aws s3 sync z:\source\folder s3://bucketname/folder --delete --cache-control max-age=12345 --acl public-read

请注意,我根本没有使用 --metadata-directive,因为使用它你会失去你的猜测内容类型,这将使像图片这样的东西不会显示在浏览器中,而是被立即下载。我的解决方案保留猜测值,并允许使用同步进行猜测。