无法让 CloudFront 提供缓存控制标头
Posted
技术标签:
【中文标题】无法让 CloudFront 提供缓存控制标头【英文标题】:Can't make CloudFront supply cache-control headers 【发布时间】:2019-03-26 11:10:21 【问题描述】:我对此进行了大量阅读,但我所看到的解决方案似乎都不适用于 IIS 网站 - 大多数似乎都建议一些服务器端解决方案,但这些都不适用于我。
我正在优化我们的一个网站,PageSpeed、YSlow 和 Lighthouse 都抱怨我从 CloudFront CDN 提供的图像没有任何缓存标头。 CDN 从 S3 存储桶提供服务。
例如https://static.edie.net/webimages/new_new_new.png(未指定过期时间)
同时显示为“有一些静态组件没有很远的到期日期”和“利用浏览器缓存来获取以下可缓存资源”
我这辈子都想不出如何让 CloudFront 为这样的图像提供缓存标头。
我已经设置了
Cache-Control: max-age=5500000
在 s3 存储桶/文件本身上,如果您通过存储桶检查文件:https://devedienet.s3.amazonaws.com/webimages/new_new.png,那么它存在缓存标头。
但这似乎不会影响 CloudFront 映像,它只有以下标头:
Age: 12153
Connection: keep-alive
Date: Mon, 22 Oct 2018 11:18:49 GMT
ETag: "940fd4d68428cf3e4f88a45aab4d7157"
Server: AmazonS3
Via: 1.1 4f95eb10423b781564e79d7c85f85795.cloudfront.net (CloudFront)
X-Amz-Cf-Id: TZAWy8U12-ohhe-dwTkCLqXHbJKI7CJqQd21I-lvq-8rloZjTew6aw==
x-amz-meta-s3b-last-modified: 20181017T105350Z
X-Cache: Hit from cloudfront
我已尝试将自定义行为添加到 CloudFront 分配的 AWS 控制面板中:
webimages/*.png
Minimum TTL: 5500000
但这似乎没有任何效果。
请注意,在添加上面的新规则后,我使文件夹中的所有图像无效,但没有骰子。
我是否遗漏了什么或误解了什么要求?
【问题讨论】:
再次使图像无效。Age: 12153
表示此特定对象在您发出此请求之前 12,153 秒从 S3 缓存。
谢谢@Michael-sqlbot 我不确定再次使它们无效会有多大帮助?自从我开始这样做以来,我已经做了几次,并且缓存控制标头从未出现过,即使重置了年龄也无济于事,不是吗?
如果对象有Cache-Control
标头,那么失效应该可以解决问题。如果Age
正在重置,则失效有效。查看来自两个 URL 的响应标头,我不相信您的 CloudFront 分配实际上指向此存储桶。我认为它指向具有相同内容副本的不同存储桶。对象不一样,即使我得到了X-Cache: Miss from CloudFront
。
@Michael-sqlbot 谢谢。是的,从 URL 中删除“开发”,您会看到实时存储桶,我只是不想发布指向它的链接。即使存储桶中的对象上存在“缓存控制”标头,当您通过 CF URL 获取对象时,它也不存在于对象上。这就是我想要的:是否可以在文件的 CF 版本上专门设置“缓存控制”标头?是通过存储桶对象标头传递,还是作为 CF 设置中的规则?谢谢!
请提供 2 个 URL,一个 S3 和一个 CloudFront,它们指向完全相同的东西。您的 s3 链接是 new_new.png,但您的 CloudFront 链接是 new_new_new.png。您无需执行任何操作即可使 Cache-Control
通过 CloudFront...它始终可以正常工作...但我们需要确定地查看完全相同的对象,并且这个问题的当前状态使这个很难确认。
【参考方案1】:
由于您通过云端从 S3 提供内容,因此您需要在将文件上传到 S3 时将以下标头添加到 S3 中的对象。过期:某个未来日期
奖励:您不需要为每个对象单独指定此标头。您可以在 S3 上一起上传一堆文件,单击下一步,然后在询问 S3 存储类的屏幕上,向下滚动并添加这些标题。并且不要忘记点击保存!
【讨论】:
谢谢,我在(旧)问题中确实提到我已经在文件的 S3 中设置了 max-age,但是当通过 CF URL 获取文件。似乎这确实有效,最终,似乎需要很长时间才能通过 CF 影响所有文件。此外,设置到期日期会有问题 - 我想要一个最大年龄,而不是特定日期。【参考方案2】:我遇到了类似的问题,所以在阅读和试验之后,我发现 Cloudfront 的最小 TTL、最大 TTL、默认 TTL 的对象缓存值没有在响应标头中显式添加缓存控制标头如果资源在服务器级别没有资源,则为资源。其次,即使资源在 S3 添加了缓存控制元数据,它也应该介于两者之间
MinTTL < s3 Cache < Max TTL
。
对象缓存值表明,对于提供的值,资源将在边缘位置缓存很长时间,并且不会在资源的响应标头中添加任何 Cache-Control。
我所做的是创建一个 Lambda 函数,并通过更新查看器响应的缓存行为设置将其添加到 Lambda 关联下。这是我的 Lambda fn。这在请求的资源中添加了 Cache-Control 标头。
'use strict';
exports.handler = (event, context, callback) =>
const response = event.Records[0].cf.response;
const headers = response.headers;
const headerCache = 'Cache-Control';
headers[headerCache.toLowerCase()] = [
key: headerCache,
value: 'max-age=1096000'
];
callback(null, response);
;
【讨论】:
以上是关于无法让 CloudFront 提供缓存控制标头的主要内容,如果未能解决你的问题,请参考以下文章
Cloudfront如何每次都避免If-Modified-Since标头请求