总而言之,您有想要通过 Amazon Cloudfront 通过签名 url 提供的私有图像,并且到期时间很短。然而,虽然通过特定 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 用于资源。一种变体是使用浏览器缓存以外的一些缓存机制,例如本地存储。这里的缺点是增加了浏览器预取的复杂性和受损的能力。