没有来自带有S3 Origin的AWS CloudFront的文件的缓存控制标头


27

我们刚刚迁移到Amazon AWS。当前,我们有一个运行良好的EC2实例。它在前端运行Nginx,在后端运行Apache。运行也很好。所有站点均已正确启动,并包含从EC2提供的文件的Cache-Control标头。

问题在于,我们放置在Amazon S3中的所有静态文件都可以通过CloudFront CDN访问。我们可以很好地访问文件(CORS没问题),但是显然CloudFront不提供带有Cache-Control标头的文件。我们想利用浏览器缓存。

我认为,EC2实例在这里没有作用,因为静态文件是由S3 + CloudFront直接提供的,请求不会发送到EC2中的Web服务器。

我完全迷路了。

问题:1)在这种情况下,如何设置缓存控件?2)是否可以设置缓存控件?是从S3还是CloudFront?

注意:我在Google中打了几页,您可以在S3中为单个对象设置页眉。实际上,这并不是特别有效的方法,因为在我的案例中,我们正在谈论多个对象。

谢谢!


请在S3中发布对象的URL和适用的CloudFront URL。我想看看您描述自己的行为。交替发布两个的CURL,显示标题。
蒂姆(Tim)

通过在console.aws.amazon.com/cloudfront/home中编辑原点,我已经能够添加自定义标头“ Expires:Sun,2027年10月15日13:46:07 GMT” 。但是,它似乎不起作用。您最后是怎么做到的?
Manolo

Answers:


31

我在Google中打了几页,您可以在S3中为单个对象设置Header。实际上,这并不是特别有效的方法,因为在我的案例中,我们正在谈论多个对象。

好吧,无论“生产性”与否,这就是它实际上是如何工作的。

CloudFront不添加 Cache-Control:标题。

CloudFront 传递 (并且也遵循,除非另行配置)Cache-Control:由原始服务器提供的标头,在这种情况下为S3。

为了Cache-Control:在提取对象时获取S3提供的标头,必须在将对象上传到S3或通过后续的put + copy操作将其添加到对象的元数据时提供标头,这些操作可用于在内部将对象复制到自身中S3,在过程中修改元数据。如果您编辑对象元数据,这就是控制台在后台执行的操作。

S3中也没有(如果您想知道的话)没有全局设置来强制存储桶中的所有对象返回这些标头-这是每个对象的属性。


更新: Lambda @ Edge是CloudFront中的一项新功能,可让您在查看器和缓存之间和/或缓存和原始之间触发针对请求和/或响应的触发器,针对简单的请求/响应对象结构运行用Node.js编写的代码由CloudFront公开。

此功能的主要应用程序之一是处理标头...因此尽管以上内容仍然很准确-CloudFront本身并未添加Cache-Control-现在Lambda函数可以将它们添加到从CloudFront返回的响应中。

Cache-Control: public, max-age=86400仅当Cache-Control响应中没有标题时,此示例才会添加。

在Origin Response触发器中使用此代码将导致每次CloudFront从起点获取对象时触发它,并在CloudFront缓存它之前修改响应。

'use strict';

exports.handler = (event, context, callback) => {
    const response = event.Records[0].cf.response;

    if(!response.headers['cache-control'])
    {
        response.headers['cache-control'] = [{ 
            key:   'Cache-Control', 
            value: 'public, max-age=86400' 
        }];
    }

    callback(null, response);
};

更新(2018-06-20):最近,我向CloudFront团队提交了功能请求,以允许将静态原始响应标头配置为原始属性,类似于现在可以添加静态请求标头的方式。扭曲,允许将每个标头配置为有条件地添加(仅在源未在响应中提供该标头的情况下)或无条件地添加(添加标头,然后从源中覆盖标头(如果存在))。

使用功能请求时,通常不会收到有关他们是否正在考虑实施新功能的确认…甚至是他们可能已经在进行新功能的确认……它们只是在完成时宣布。因此,我不知道这些措施是否会实施。有一个论点是,由于该功能已经可以通过Lambda @ Edge获得,因此基本功能中不需要它……但是我的反对意见是,如果没有以下功能,基本功能就无法完成功能:进行简单的静态响应标头操作,并且如果这是唯一需要触发器的原因,则在经济上和增加的等待时间中,要求Lambda触发器是不必要的成本(即使两者都不一定是奇特的成本)。


仍然很烦。
艾丽卡·凯恩


1
Tada,的确,@ Kunal。这就是我在答案中所说的“通过后续的put + copy操作添加到对象元数据中”的示例请谨慎使用并进行测试,因为存在一些警告。它将重置所有日期戳,并可能对加密产生影响。它还可能将对象etags从多部分格式更改为单部分格式,这是一种不同的算法,并且会使将etags存储在其他位置以进行将来完整性检查的任何系统感到困惑。如果在存储桶上启用了版本控制,则除非清理旧版本,否则存储成本将增加一倍。
Michael-sqlbot

1
现在,新的Lambda @ Edge服务还提供了一种机制,该机制允许即时添加Cache-Control响应标头(以及其他)。我用一个可行的例子来更新答案。
Michael-sqlbot

1
@Broshi角色的“信任策略”需要同时列出lambda和edgelambda服务。看看docs.aws.amazon.com/lambda/latest/dg/…
Michael-sqlbot
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.