caching - 亚马逊云端 : private content but maximise local browser caching

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

对于我的网络应用程序中的 JPEG 图像传输,我正在考虑使用 Amazon S3(或 Amazon Cloudfront
如果结果证明是更好的选择)但有两个,可能是相反的,
要求:

  • 图片是私有(private)内容;我想使用过期时间短的签名 URL。
  • 图像很大;我希望它们被用户的浏览器长期缓存。

  • 我正在考虑的方法是:
  • 用户请求 www.myserver.com/the_image
  • 我服务器上的逻辑确定允许用户查看图像。如果他们被允许...
  • 将浏览器 (is HTTP 307 best ?) 重定向到签名的 Cloudfront URL
  • 签名的 Cloudfront URL 在 60 秒后过期,但其响应包括“Cache-Control max-age=31536000, private

  • 我预见的问题是下一次页面加载时,浏览器会寻找
    www.myserver.com/the_image 但其缓存将用于已签名的 Cloudfront URL。我的服务器
    由于非常短,第二次将返回一个不同的签名 Cloudfront URL
    过期时间,所以浏览器不会知道它可以使用它的缓存。

    有没有办法让我的网络服务器代理来自 Cloudfront 的图像(这显然否定了所​​有
    使用 Cloudfront 的好处)?


    想知道我是否可以用 etag 做些什么和 HTTP 304但不能完全加入点...

    最佳答案

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

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

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

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

    如果您希望客户端从缓存中受益,则必须将其发送到相同的 url。例如,您不能将客户端定向到以下 url 并期望客户端使用来自第一个 url 的缓存响应:
    http://[domain].cloudfront.net/image.jpg?Expires=5000&Signature=[Signature]
    

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

    因此,您陷入了这样一种情况,即为了从缓存响应中受益,您必须将客户端发送到与第一个请求相同的 url。有可能实现这一点的方法(cookie、本地存储、服务器脚本等),假设您已经实现了一种。

    接下来您必须考虑缓存只是一个建议,即使这样也不是保证。如果您希望客户端缓存图像并将原始 url 提供给它以从缓存中受益,那么您将面临缓存未命中的风险。如果在 url 过期时间后缓存未命中,则原始 url 不再有效。然后客户端无法显示图像(来自缓存或提供的 url)。

    当到期时间在 url 中时,您正在寻找的行为根本无法通过常规缓存提供。

    由于无法实现所需的行为,您可能会考虑下一个最佳选项,其中每个选项都需要放弃您需求的一个方面。按照我考虑的顺序:
  • 如果您放弃较短的到期时间,您可以使用更长的到期时间并轮换网址。例如,您可以将 url 到期时间设置为午夜,然后为当天的所有请求提供相同的 url。您的客户将受益于当天的缓存,这可能总比没有好。明显的缺点是您的网址的有效期更长。
  • 如果您放弃内容交付,您可以从服务器提供图像,该服务器检查每个请求的访问权限。客户端将能够根据需要缓存资源,这可能比内容交付更好,具体取决于缓存命中的频率。一种变体是将 Amazon CloudFront 换成另一个提供商,因为可能有其他支持这种行为的内容交付网络(尽管我不知道有)。根据您的特定访问者,内容交付网络的丢失可能是不利的,也可能无关紧要。
  • 如果您放弃单个静态 HTTP 请求的简单性,您可以使用客户端脚本来确定应该发出的请求。例如,在 javascript 中,您可以尝试使用原始 url 检索资源(以从缓存中受益),如果失败(由于缓存未命中和过期过期)请求新的 url 用于资源。一种变体是使用浏览器缓存以外的一些缓存机制,例如本地存储。这里的缺点是增加了复杂性并损害了浏览器预取的能力。
  • 关于caching - 亚马逊云端 : private content but maximise local browser caching,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14552997/

    相关文章:

    Android缓存数据和更新策略?

    django - 找出 Django 代码在哪个用户下运行

    amazon-s3 - 支持 S3 的 Scrapy

    amazon-web-services - aws s3 ls 递归 grep 扩展 '.mov' 和总大小

    java - Java 中的缓存函数?

    asp.net - 如何为客户端和服务器缓存设置不同的缓存过期时间

    java - Java中具有过期控制的分布式缓存

    amazon-web-services - aws cloudformation 错误 : Could not unzip uploaded file. 请检查您的文件,然后尝试重新上传

    amazon-web-services - AWS应用程序负载均衡器不转发请求

    http - IE 缓存行为 : response 304 followed by 200's on same resource?