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

时间:2013-01-27 22:20:47

标签: caching amazon-web-services amazon-s3 http-headers amazon-cloudfront

对于我的网络应用中的JPEG图像传送,我正在考虑使用Amazon S3(或Amazon Cloudfront 如果它是更好的选择)但有两个,可能是对立的, 要求:

  1. 图片是私人内容;我想使用过期时间短的签名网址。
  2. 图像很大;我希望用户的浏览器长期缓存它们。
  3. 我想的方法是:

    1. 用户请求www.myserver.com/the_image
    2. 我服务器上的逻辑确定允许用户查看图像。如果他们被允许......
    3. 将浏览器(is HTTP 307 best ?)重定向到已签名的Cloudfront URL
    4. 已签名的Cloudfront URL将在60秒后过期,但其响应中包含“Cache-Control max-age=31536000, private
    5. 我预见到的问题是,下次加载页面时,浏览器会寻找 www.myserver.com/the_image但其缓存将用于签名的Cloudfront URL。我的服务器 由于非常短,第二次将返回不同的签名Cloudfront URL 到期时间,因此浏览器不会知道它可以使用其缓存。

      如果没有我的网络服务器代理来自Cloudfront的图像(这显然会否定所有 使用Cloudfront的好处?

      想知道我可以对etagHTTP 304做些什么,但不能完全加入点......

3 个答案:

答案 0 :(得分:9)

总而言之,您希望通过签名网址通过Amazon Cloudfront提供私有图片,且期限很短。但是,虽然特定URL的访问可能是有时间限制的,但是即使在URL到期之后,客户端仍希望在后续请求中从缓存提供图像。

无论客户端如何到达云端URL(直接或通过某些服务器重定向),图像的客户端缓存只会与用于请求图像的特定URL(而不是任何其他URL)相关联。

例如,假设您的签名网址如下(为了示例目的,缩短了到期时间戳):

http://[domain].cloudfront.net/image.jpg?Expires=1000&Signature=[Signature]

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

http://[domain].cloudfront.net/image.jpg?Expires=5000&Signature=[Signature]

目前没有缓存控制机制来解决这个问题,包括ETag,Vary等.Web上客户端缓存的本质是缓存中的资源与url相关联,其他机制的目的是帮助客户确定特定网址标识的资源的缓存版本何时仍然是新鲜的。

因此,您将陷入这样一种情况:要从缓存的响应中受益,您必须将客户端发送到与第一个请求相同的URL。有可能实现这一目标的方法(cookie,本地存储,服务器脚本等),让我们假设你实现了一个。

接下来你必须考虑缓存只是一个建议,即使这样也不是保证。如果您希望客户端将图像缓存并将其提供给原始URL以从缓存中受益,则可能会出现缓存未命中的风险。在URL到期时间之后缓存未命中的情况下,原始URL不再有效。然后,客户端无法显示图像(来自缓存或提供的URL)。

当到期时间在网址中时,传统缓存无法提供您所寻找的行为。

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

  1. 如果您放弃短暂的到期时间,您可以使用更长的到期时间并轮换网址。例如,您可以将url expiry设置为午夜,然后为当天的所有请求提供相同的url。您的客户将受益于当天的缓存,这可能比没有更好。明显的缺点是你的网址有效期更长。

  2. 如果您放弃内容传送,则可以从服务器提供图像,该服务器会检查每个请求的访问权限。客户端将能够根据需要缓存资源,这可能比内容传递更好,具体取决于缓存命中的频率。这种情况的一种变体是将Amazon CloudFront换成另一个提供商,因为可能有其他内容交付网络支持这种行为(虽然我不知道)。内容分发网络的丢失可能是一个缺点,也可能无关紧要,具体取决于您的特定访问者。

  3. 如果放弃单个静态HTTP请求的简单性,则可以使用客户端脚本来确定应该进行的请求。例如,在javascript中,您可以尝试使用原始URL检索资源(以从缓存中受益),如果它失败(由于缓存未命中和失效的到期),请求使用新的URL用于资源。这种情况的一种变体是使用除浏览器缓存之外的一些缓存机制,例如本地存储。这里的缺点是增加了复杂性并降低了浏览器预取的能力。

答案 1 :(得分:-1)

保存用户+图片+到期时间列表 - >云端链接。如果用户具有未过期的云端链接,请将其用于图像,而不是生成新图像。

答案 2 :(得分:-1)

看来你已经解决了这个问题。您说您的服务器正在向云端URL(签名URL)发出重定向http 307,因此浏览器仅缓存前端URL而不是您的URL(www.myserver.com/the_image)。所以场景如下:  客户端1检查www.myserver.com/the_image - >重定向到CloudFront网址 - >内容被缓存   CloudFront网址现已过期。

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

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