首页 > 解决方案 > 如何使用不同的 aws s3 预签名 url 使浏览器缓存相同的图像?

问题描述

我为我的用户生成了与此类似的 url,以从我的 aws s3 存储桶中检索图像文件:

https://resource.my-company.com/tYERrR13341/q1/something.jpg?response-expires=Thu%2C%2008%20Nov%202018%2007%3A26%3A21%20GMT&AWSAccessKeyId=TTKIAJJBATJ89740989&Expires=1541661981&Signature=J49ebmKMdZ%2FZqwupfaD39f9e716831

Expires有时,用户可能会刷新页面,并且同一资源的 url 会为和获取一组新值Signature

浏览器会将这两个 url 视为不同的两个对象,并会尝试再次从 s3 存储桶中下载资源。

它会导致一些性能问题。是否有可能让浏览器意识到,尽管 url 的参数部分存在差异,但用户正在尝试检索相同的资源并因此从其本地缓存中检索它?

标签: amazon-web-servicesamazon-s3pre-signed-url

解决方案


我遇到了同样的问题,并通过缓存图像 presigned-url 链接解决了这个问题,这将解决问题。

当您从 AWS 请求一个预签名的 url 时,它会返回一个带有过期 & 签名的链接,该链接指向您存储桶中的源文件,每次您进行刷新时:服务器会将请求传递给 AWS,然后检索新的过期 &浏览器一无所知的签名,因此它将再次获取相同的图像。

告诉浏览器不要再获取它的方法是在刷新页面时发回相同的签名!这听起来很容易,但它可能会变得混乱,所以请耐心等待。

我提出的解决方案是使用“Redis”缓存层,将浏览器加载的图像映射到串行。

如果 userA 加载页面,您只需检查它是否已被同一用户和同一浏览器和 MacAddress/IP 使用“串行”访问过,您应该将其添加到浏览器的本地存储中,

serial structure = (browser-type&name + userID + MacAddress/IP),这是为了确保在 userA 同时从不同的设备和浏览器登录时它可以工作,并确保每次 userA 加载时创建相同的序列来自此特定浏览器和设备的页面/图像。

如果 userA 没有序列号保存到本地存储,则将其添加到本地存储并检查序列号是否存在于 Redis 中(用户可能之前登录并清除了浏览器缓存),如果是,则删除包含的附加对象图像的预签名链接作为参数:

"serial" : 
      
{ 
       
         imageID_1 : "https://s3.bucket.xxx/imageID_1.jpg?.......xyz1",

         imageID_2 : "https://s3.bucket.xxx/imageID_2.jpg?.......xyz2",

         imageID_3 : "https://s3.bucket.xxx/imageID_3.jpg?.......xyz3"

 }

然后为必须在页面上加载的每个 imageID/key 请求新的预签名 url,并将它们附加到 Redis 中的“串行”对象参数。如果不是,那么只需添加两个“串行”+对象参数:

"serial" : 
      
{ 
       
         imageID_1 : "https://s3.bucket.xxx/imageID_1.jpg?.......abc1",

         imageID_2 : "https://s3.bucket.xxx/imageID_2.jpg?.......abc2",

         imageID_3 : "https://s3.bucket.xxx/imageID_3.jpg?.......abc3"

 }

如果浏览器将串行缓存到本地存储中,您还必须检查每个请求是否存在 imageID 链接到串行的对象参数中,以便为其创建预签名 URL(如果不存在)然后添加它作为对象的新参数:

"serial" : 
      
{ 
       
         imageID_1 : "https://s3.bucket.xxx/imageID_1.jpg?.......abc1",

         imageID_2 : "https://s3.bucket.xxx/imageID_2.jpg?.......abc2",

         imageID_3 : "https://s3.bucket.xxx/imageID_3.jpg?.......abc3",

         imageID_4 : "https://s3.bucket.xxx/imageID_4.jpg?.......abc4",


 }

这是为了防止用户已经在浏览器的本地存储中保存了一个序列号,告诉之前有一些加载的图像,所以我们必须检查 userA 是在请求​​之前加载的相同图像还是他正在请求新的图像。

最后,您必须检查是否由于任何原因未加载或禁止从浏览器访问图像(用于检查并向服务器报告的字体端代码),在这种情况下,您只需删除串行附加对象并附加新的presigned-urls 然后将它们发送回前端(浏览器)。


推荐阅读