158

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

4

10 回答 10

247

现在有 3 种方法可以完成此操作:通过 AWS 控制台通过命令行通过 s3cmd 命令行工具


AWS 控制台说明

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

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

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


AWS 命令​​行解决方案

最初,当我创建这个存储桶策略时是不行的,所以我想出了如何使用 aws-cli 来完成它,而且它非常巧妙。在研究时,我在野外找不到任何例子,所以我想我会发布一些我的解决方案来帮助有需要的人。

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

要使用命令行上指定的元数据,您需要添加“--metadata-directive REPLACE”标志。这里有一些例子。

对于单个文件

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

对于整个存储桶(注意 --recursive 标志):

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

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

只有jpg和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"

这可能是由过时的 awscli 引起的 - 请参阅下面的@eliotRosewater 的回答


S3cmd 工具

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

有关完整说明,请参阅下面的 @ashishyadaveee11 的帖子


希望能帮助到你!

于 2015-03-26T14:13:52.110 回答
60

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

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

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

于 2017-11-02T10:17:29.907 回答
24

脚步

  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/
于 2016-02-04T13:27:49.537 回答
15

如果我的声誉得分 > 50,我会发表评论。但这还不是(还)所以这是另一个完整的答案。


一段时间以来,我一直在努力解决这个问题。直到我找到并阅读了文档。在这里分享,以防它帮助其他人:

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

aws s3 cp \
  --metadata-directive REPLACE \
  --cache-control max-age=1,s-maxage=1 \
  s3://bucket/path/file \
  s3://bucket/path/file
  • --metadata-directive REPLACEcp在 S3 中修改现有文件的元数据时需要“ ”
  • 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
于 2018-02-01T21:53:06.393 回答
8

我认为您不能在存储桶级别指定此内容,但有一些解决方法可供您使用。

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

  2. 在文件的 url 中指定响应标头。您需要使用预签名的 url 才能工作,但您可以在查询字符串中指定某些响应标头,包括cache-controlexpires。有关可用选项的完整列表,请参阅:http ://docs.amazonwebservices.com/AmazonS3/latest/API/RESTObjectGET.html?r=5225

于 2012-05-04T08:28:25.930 回答
4

您始终可以在 S3 上的 PUTOBJECT 上使用触发器配置 lambda,该 lambda 将简单地更改刚刚放置的此特定对象的标头。

然后你可以最后一次运行上面提到的复制命令,所有的新对象都将被 lambda 修复。

更新:

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

于 2017-06-03T21:35:46.027 回答
2

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

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

  • 创建 CloudFront 分配
  • 添加 S3 存储桶作为源
  • 创建一个修改响应头的 lambda 函数
  • 使用 CloudFront 分配的 URL 访问文件

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

于 2020-08-31T17:38:29.473 回答
1

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

“未知选项:--元数据指令,替换”

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

sudo apt-get 安装 awscli

这安装了缺少 --metadata-directive 命令的旧版本的 awscli。所以我用 sudo apt-get remove awscli 来删除它。

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

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

于 2016-10-16T21:11:45.393 回答
1

想我会分享我的用法,因为以前的答案误导了我。AWS CLI 只有两个命令:

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

这就是已经存在的东西,使用cp。这样的设置--cache-control是一个有效的选项。

如果您正在上传,您不妨sync,其命令是:

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

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

于 2021-11-04T16:26:15.437 回答
0

以前的答案要么与问题不真正对应,要么产生成本(Lambda)。

您应该做的是在上传文件(PutObject 或 MultiPartUpload)时设置“缓存控制”标头。

根据您的语言,它可能会有所不同。文档不是很清楚(大概是 AWS 希望您用其他解决方案向他们付款)。

PHP的一个例子:

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

Go 的另一个例子:

cc := "max-age=31536000,public"
input := &s3.PutObjectInput{
    ...,
    CacheControl: &cc,
}
于 2021-09-07T19:54:41.767 回答