亚马逊S3静态网站托管缓存

44
我使用Amazon S3 Web托管我的静态html,js,css(等)文件。替换了我的index.html文件后,通过浏览器访问仍然显示旧版本。我想在存储桶(bucket)上设置默认ttl(而不是针对其中特定的对象)。我在这个链接上找到了一些信息: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesDefaultTTL 但是在控制面板中找不到"Object Caching"设置。有人可以指出它在哪里吗?

1
你引用的链接是关于CloudFront而不是S3的。如果你没有使用CloudFront,这些信息就不相关了。如果你正在使用CloudFront,那么在问题中应该提到这一点。 - Michael - sqlbot
相关内容:https://dev59.com/iWEh5IYBdhLWcg3wXCZL - Flimm
4个回答

59

这是一条Amazon S3链接,可以回答你的问题。根据亚马逊的说法,如果你不使用第三方工具(该页面链接了几个工具),则无法为整个存储桶设置缓存控制标头。我发现的一个工具描述了如何为使用PUT请求提交的对象(或使用其工具批量提交的对象)设置缓存指令。请查看BucketExplorer了解更多信息。

以下是亚马逊的说明(因为S.O.不喜欢依赖可能会更改或消失的外部链接):

使用Amazon S3控制台将Cache-Control或Expires标头字段添加到Amazon S3对象中

  1. 登录AWS管理控制台并打开Amazon S3控制台,网址为https://console.aws.amazon.com/s3
  2. 在Amazon S3控制台中,单击包含文件的存储桶名称。
  3. 在对象列表中,选择要添加标头字段的第一个对象。
  4. 单击操作,然后单击属性
  5. 在右侧面板中,展开元数据
  6. 单击添加更多元数据
  7. 键列表中,单击Cache-ControlExpires(视情况而定)。
  8. 字段中,输入相应的值:
  9. 对于Cache-Control字段,请输入:max-age=您希望对象停留在CloudFront边缘缓存中的秒数
  10. 对于Expires字段,请输入HTML格式的日期和时间。
  • 点击保存
  • 如果您想要为其他对象添加标题字段,请单击下一个对象的名称,然后重复步骤5到9。


    5
    请注意,您也可以使用相同的步骤在文件夹级别上管理此行为。 - JLM
    当我审查Amazon S3链接时,有一些为我提供澄清的东西。如果你想要Cloudfront缓存但不缓存浏览器,简而言之,请确保s3对象的最大年龄为零,但Cloudfront设置了最小TTL。 - Greg Micek
    这个功能运行良好,但当我们推送新的构建并替换文件时,它会删除缓存头信息。有没有办法自动设置这些文件的头信息? - Cycl0n3

    12

    2022 AWS CLI V2 方法

    最简单的方法是使用 AWS CLI (S3)。这也可以通过像 GitHub Actions 这样的工具完全自动化地免费完成。

    静态站点不应该在 HTML 文件上设置长期有效的 cache-control,因为用户直到浏览器缓存过期或手动清除缓存之前都无法看到更新后的版本。


    由于 AWS CLI 的限制,您需要执行以下操作才能为整个存储桶设置缓存。


    通用示例

    上传内容并 --delete 旧的 S3 内容,并在所有内容上设置 cache-control

    aws s3 sync [YOUR_LOCAL_SOURCE_CODE_PATH] s3://[BUCKET_NAME] --delete --cache-control max-age=31536000
    

    递归地从所有 HTML 文件中删除 cache-control 标头,并将文件类型设置回 HTML

    aws s3 cp s3://[BUCKET_NAME] s3://[TO_BUCKET_NAME] --recursive --exclude "*" --include "*.html" --metadata-directive REPLACE --cache-control max-age:no-cache --content-type text/html
    

    注意事项

    • TO_BUCKET_NAME 几乎总是与 BUCKET_NAME 相同。
    • 如果您在 AWS S3 中修改了 HTML 文件的元数据,则还必须设置 content-type,否则它将自动设置为通用类型,导致浏览器下载文件而不是在浏览器中呈现。

    示例

    // delete old files and upload files from the local directory to the s3 bucket, and set the cache-control header on every file.
    aws s3 sync ./out s3://www.test.com --delete --cache-control max-age=31536000
    
    // copy all files and remove cache control header from only HTML files and set back to html content type
    aws s3 cp s3://www.test.com s3://www.test.com --recursive --exclude "*" --include "*.html" --metadata-directive REPLACE --cache-control max-age:no-cache --content-type text/html
    
    // bonus - if using CloudFront - small site can invalidate all cache (/*)
    aws cloudfront create-invalidation --distribution-id=123ABCDEFG --paths "/*"
    

    1
    嗨,肖恩。关于我所做的编辑,你随后又撤销了它,我来简单解释一下。如果你坚持要评论另一个答案,那么你应该在获得特权后对该答案进行评论。不要使用答案来回复答案-这不是一个分级讨论论坛。我认为你提供的信息对OP和其他可能遇到同样问题的人有帮助,因此值得调整你的帖子,使其听起来像一个答案,并避免被删除。 - Mogsdad

    2
    如果您使用AWS CLI,可以为每个同步对象添加--cache-control--metadata directive
    以下是我的npm脚本:
     "scripts": {
        "prod": "NODE_ENV=production webpack --config ./webpack.config.prod.js",
        "sync": "aws s3 sync public/ s3://[BUCKET_NAME] --delete --cache-control max-age=31536000",
        "invalidate": "aws cloudfront create-invalidation --distribution-id [DISTRIBUTION_ID] --paths \"/*\"",
        "deploy": "npm run prod && npm run sync && npm run invalidate"
      },
    

    -5

    是的。如果您正在使用CloudFront分发 - 您只需要检查无效和为什么您的对象无效未正常工作。TTL值是多少。

    您使用CDN吗?


    设置S3缓存控制与设置Cloudfront TTL不同,后者仅控制文件在Cloudfront缓存中保留的时间,与浏览器缓存无关。 - Franco

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