如何在AWS S3中添加缓存控制?

98

我使用s3cmd命令将20000个文件移动到了AWS S3。现在我想为所有的图片(.jpg)添加缓存控制。

这些文件位于(s3://bucket-name/images/)。我如何通过s3cmd为所有图片添加缓存控制,或者是否有其他方法可以添加标头?

谢谢

10个回答

95
请尝试使用当前上游主分支(https://github.com/s3tools/s3cmd),因为它现在有一个modify命令,用法如下:
./s3cmd --recursive modify --add-header="Cache-Control:max-age=86400" s3://yourbucket/

5
谢谢回复,我尝试了这个方法,但是出现了错误:ERROR: Invalid command: u'modify'。请问有什么解决办法吗? - Rajaraman
@Rajaraman 你知道这个的情况吗?在这个步骤之后,它显示访问被拒绝。 - shajin
2
这个可以工作...已经测试过了,使用的是s3cmd版本1.5.0-rc1。但是:这会将对象的Content-type标头更改为"binary/octet-stream"!已经测试过一个PNG文件。 - Hardy
1
我遇到了与@Hardy相同的问题。它还从我的所有文件中删除了公共可读性。小心。 - Andrew B.
1
看起来 Content-Type 的 bug 已经在 #406 中得到修复。 - josh3736
显示剩余5条评论

79

还可以使用AWS自己的客户端:

aws s3 sync /path s3://yourbucket/ --cache-control max-age=604800

2
如果您正在从计算机的本地路径上传到AWS,并希望所有内容保持适当的缓存控制,则此方法可行。 - youanden
25
这段话的意思是在首次同步时设置缓存头有效,但不会更新已有的文件。如果想强制更新,可以使用以下命令:find . -type f -exec touch '{}' \;; aws s3 sync /path s3://yourbucket/ --recursive --cache-control max-age=604800 - Matt Byrne
3
OP正在要求更新S3中现有的文件,而不是上传新文件。 - Beowulfenator
3
“--recursive”参数是否仍然必要?CLI文档似乎没有将其列为参数。http://docs.aws.amazon.com/cli/latest/reference/s3/sync.html - Corey McMahon
2
@MattByrne 自1.7.12版本开始,必须省略--recursive。https://github.com/aws/aws-cli/blob/develop/CHANGELOG.rst#1712 - Bernhardt Scherer
显示剩余4条评论

42

我的存储桶里有 mp4、jpg 和其他文件。我想更新的文件存储在“子存储桶”中(例如:https://s3.amazonaws.com/my.bucket/sub-directory/my-video.mp4)。在我的情况下,我只想更新 mp4 文件的缓存控制:

aws s3 cp \
   s3://my.bucket/sub-directory/ s3://my.bucket/sub-directory/ \
   --exclude '*.jpg' --exclude '*.png' \
   --cache-control 'max-age=31104000' \
   --recursive

为了测试这会做什么,您可以使用--dryrun标志:

aws s3 cp --dryrun \
   s3://my.bucket/sub-directory/ s3://my.bucket/sub-directory/ \
   --exclude '*.jpg' --exclude '*.png' \
   --cache-control 'max-age=31104000' \
   --recursive

我遇到了这个错误:"调用CopyObject操作时:此复制请求是非法的,因为它试图将一个对象复制到自身而不改变对象的元数据、存储类、网站重定向位置或加密属性。" - Flimm
9
为了修复它,我必须添加 --metadata-directive REPLACE --acl public-read - Flimm
我最初使用metadata指令来使其工作,但结果改变了对象的内容类型,而不仅仅是添加 --acl public-read - Matt Gaunt

27

使用AWS CLI,您可以对S3中的对象进行元数据调整(例如缓存控制),而无需重新上传它或使用任何第三方工具。以下是操作步骤:将对象复制到自身并用您选择的设置覆盖元数据:

aws s3api copy-object --copy-source <bucket-name>/<file> --bucket <bucket-name> --key <file> --metadata-directive REPLACE --cache-control "max-age=3600"

在find命令中处理此命令,以便对已经存在于存储桶中的现有文件集执行此操作,正如您所提到的:

find . -type f -exec aws s3api copy-object --copy-source <bucket-name>/{} --bucket <bucket-name> --key {} --metadata-directive REPLACE --cache-control "max-age=3600"

用您桶的名称替换<bucket-name>

警告:这将覆盖所有现有文件的元数据,例如acl,请在命令中添加额外的标志以设置您需要的内容,例如--acl public-read以提供完全公共访问权限。 (感谢@jackson)


7
这样做会设置我的缓存头,但会移除我在文件上设置的“public”权限(导致它们在我的S3托管网站上无法查看)。为了保持文件公开,我必须使用--acl public-read命令运行。 - Jackson
它还将我的内容类型更改为二进制/八位字节 -- 不好 - Joe Love

19

如果您想避免使用第三方工具,并且这是一次性任务,您可以使用AWS控制台。

  1. 浏览到您的S3存储桶
  2. 选择要更改的所有对象
  3. 单击操作 - > 更改元数据
  4. 为键选择缓存控件,输入您想要的任何控件作为值
  5. 保存

3
未来如何对上传的文件进行更改?例如,当您通过S3 API或在Web控制台手动上传文件时,如何保持文件夹/存储桶上设置的缓存控制(Cache-Control)不变。 - Andrei F

5
PUT / ObjectName HTTP/1.1 
Host: BucketName .s3.amazonaws.com 
Date: date 
x-amz-meta-Cache-Control : max-age= <value in seconds> 
Authorization: signatureValue 

每个元数据设置都包含一个键值对。缓存控制元数据键是“Cache-Control”,值是“max-age=<以秒为单位希望从缓存访问对象的时间>” 您可以通过两种方式向Amazon S3对象设置缓存控制自定义标头,发送HTTP PUT请求到Amazon S3服务器并使用适当的标头:
1. 使用Amazon S3 REST API PUT Object Request设置缓存控制元数据-如果您是程序员,则可以编写自己的软件程序,使用Amazon S3 REST或SOAP API设置PUT对象请求的自定义标头。本网站仅涉及Amazon S3 REST API,请参阅AWS文档网站以了解如何使用SOAP API。
2. 使用Bucket Explorer用户界面设置缓存控制元数据-如果您喜欢使用鼠标单击而不是编写软件程序来设置自定义HTTP标头,您可以使用Bucket Explorer的用户界面。
通过此自定义HTTP标头,您可以指定必须遵循的缓存行为,并防止缓存干扰请求或响应。
有关更多信息,请查看如何为Amazon S3对象设置缓存控制标头?

1

这是目前最好的方法,而且不会遇到其他答案中提到的错误:

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

1
(由于问者要求其他方式)您还可以通过 aws-cli 来完成,例如(v:aws-cli/1.8.8 Python/2.7.2 Darwin/12.5.0):
aws s3api put-object \
--bucket mybucket \
--key my/key \
--cache-control max-age=1 \
--body myfile.txt

请注意,您将重写任何现有对象。

0
只需将s3cmd升级到1.5.1版本,问题就会得到解决。

0

另一个非常简单的方法是使用S3浏览器:http://s3browser.com/ 您只需按住Shift键单击或Ctrl + A选择您想要的所有图像;然后转到“Http Headers”选项卡,单击“添加新标头”,然后单击“应用更改”。它会自动保留所有其他权限和标头。

如果您经常使用S3,则这是一个很好的应用程序,特别是如果您有大量上传(在ftp、dropbox或其他方面没有比它更好的东西!)


1
为什么会有踩票?OP说“s3cmd或者还有其他方法添加头部”,S3浏览器在批量头部编辑方面非常出色,比AWS控制台的Web界面好得多。 - Reece
1
我没有给你点踩,但这个想法不好,因为它难以维护。每次有人添加新文件时,你都必须手动去做这件事(或者试图训练他们去做)。更好的解决方案是“运行此脚本上传您的文件”,它总是能正确地工作。无需手动干预和遵循步骤。 - Ryan Shillington
2
为什么人们要使用GUI(s)FTP客户端,如FileZilla或Cyberduck,而不是Linux SFTP命令?类似的坏主意吗?理论上,您可以编写几乎任何现有GUI解决方案的脚本。我认为其是否是好主意或坏主意的关键在于使用的上下文。我发现S3浏览器是一个有用的工具,不认为将其作为选项呈现会有害。 - Reece

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