Caching Amazon Cloudfront:私有内容,但最大化本地浏览器缓存

Caching Amazon Cloudfront:私有内容,但最大化本地浏览器缓存,caching,amazon-web-services,amazon-s3,http-headers,amazon-cloudfront,Caching,Amazon Web Services,Amazon S3,Http Headers,Amazon Cloudfront,对于在我的web应用程序中交付JPEG图像,我正在考虑使用AmazonS3(或AmazonCloudFront) 如果结果是更好的选择),但有两个,可能是相反的, 要求: 图像是私人内容;我想使用有签名的URL并缩短过期时间 图像较大;我希望用户的浏览器能够长期缓存它们 我想的方法是: 用户请求www.myserver.com/the_image “我的服务器”上的逻辑决定允许用户查看图像。如果他们被允许 将浏览器(HTTP 307是否最佳?)重定向到已签名的Cloudfront URL 签名的

对于在我的web应用程序中交付JPEG图像,我正在考虑使用AmazonS3(或AmazonCloudFront) 如果结果是更好的选择),但有两个,可能是相反的, 要求:

  • 图像是私人内容;我想使用有签名的URL并缩短过期时间
  • 图像较大;我希望用户的浏览器能够长期缓存它们
  • 我想的方法是:

  • 用户请求www.myserver.com/the_image
  • “我的服务器”上的逻辑决定允许用户查看图像。如果他们被允许
  • 将浏览器(
    HTTP 307是否最佳?
    )重定向到已签名的Cloudfront URL
  • 签名的Cloudfront URL将在60秒后过期,但其响应包括“
    缓存控制最大年龄=31536000,私有
  • 我看到的问题是,下次加载页面时,浏览器将查找 www.myserver.com/the_映像,但其缓存将用于签名的Cloudfront URL。我的服务器 将在第二次返回另一个已签名的Cloudfront URL,原因是非常短 过期时间,因此浏览器不会知道它可以使用其缓存

    有没有办法绕过这个问题,而不让我的Web服务器代理来自Cloudfront的图像(这显然否定了所有 使用Cloudfront的好处)?


    想知道我是否可以用
    etag
    htp304
    做点什么,但不能很好地连接点…

    保存一个用户+图像+过期时间->cloudfront链接列表。如果用户具有未过期的cloudfront链接,请将其用于图像,而不要生成新的图像。

    您似乎已经解决了该问题。您说您的服务器正在向cloudfront URL(签名URL)发出重定向
    http 307
    ,因此浏览器只缓存cloudfront URL而不是您的URL(www.myserver.com/the_image)。因此,情况如下: 客户端1检查www.myserver.com/the_image->是否重定向到CloudFront URL->内容是否缓存 CloudFrontURL现在过期

    客户端1再次检查www.myserver.com/the_image->是否重定向到相同的CloudFront URL->从缓存中检索内容,而不重新获取CloudFront内容


    客户端2检查www.myserver.com/the_image->被重定向到CloudFront URL,该URL拒绝其访问,因为签名已过期。

    总之,您希望通过签名URL在很短的过期时间内通过Amazon CloudFront提供私有图像。然而,尽管特定url的访问可能是有时间限制的,但希望客户端在后续请求中甚至在url过期之后从缓存中服务图像

    无论客户机如何到达cloudfront url(直接或通过某些服务器重定向),映像的客户机缓存将仅与用于请求映像的特定url(而不是任何其他url)关联

    例如,假设您的签名url如下(例如,缩短到期时间戳):

    如果希望客户端从缓存中获益,则必须将其发送到同一url。例如,您不能将客户端指向以下url并期望客户端使用来自第一个url的缓存响应:

    http://[domain].cloudfront.net/image.jpg?Expires=5000&Signature=[Signature]
    
    目前没有缓存控制机制来解决这个问题,包括ETag、Vary等。web上客户端缓存的本质是缓存中的资源与url关联,其他机制的目的是帮助客户机确定由特定url标识的资源的缓存版本何时仍然是新的

    因此,为了从缓存响应中获益,您必须将客户端发送到与第一个请求相同的url。有一些潜在的方法可以实现这一点(cookies、本地存储、服务器脚本等),我们假设您已经实现了一种

    接下来,你必须考虑缓存只是一个建议,即使它不是一个保证。如果您希望客户端缓存图像并将其作为原始url提供,以从缓存中获益,那么您就有缓存丢失的风险。如果在url过期后发生缓存未命中,则原始url不再有效。然后,客户端将无法显示图像(从缓存或提供的url)

    当到期时间在url中时,传统的缓存无法提供您想要的行为

    由于期望的行为无法实现,您可能会考虑下一个最佳选项,每个选项都需要放弃您的需求的一个方面。按顺序我会考虑它们:

  • 如果您放弃较短的到期时间,则可以使用较长的到期时间并旋转URL。例如,您可以将url到期时间设置为午夜,然后为当天的所有请求提供相同的url。您的客户机将受益于当天的缓存,这可能比根本没有要好。明显的缺点是URL的有效期更长

  • 如果您放弃内容交付,您可以从服务器提供图像,该服务器会检查每个请求的访问权限。客户端将能够缓存资源,只要您愿意,这可能比内容交付更好,具体取决于缓存命中的频率。另一个变体是将Amazon CloudFront交易给另一个提供商,因为可能有其他内容交付网络支持这种行为(尽管我不知道有)。失去内容交付网络可能是一个不利因素,也可能无关紧要,具体取决于您的特定访问者

  • 如果放弃单一静态HTTP请求的简单性,可以使用客户端脚本来确定应该发出的请求。例如,在javascript中,您可以尝试使用原始url检索资源(以从缓存中获益),如果失败(由于缓存未命中和过期),则请求
    http://[domain].cloudfront.net/image.jpg?Expires=5000&Signature=[Signature]