Rails ActiveStorage:如何避免每个映像进行一次重定向? [英] Rails ActiveStorage: how to avoid one redirect for each image?

查看:85
本文介绍了Rails ActiveStorage:如何避免每个映像进行一次重定向?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您使用ActiveStorage,并且您的页面中包含N张图片,那么您会向Rails应用程序收到N个额外的请求(即N个重定向).如果页面上有几十个图像,这意味着浪费大量服务器资源.

If you use ActiveStorage and you have a page with N images you get N additional requests to your Rails app (i.e. N redirects). That means wasting a lot of server resources if you have tens of images on a page.

我知道重定向对于签名的URL很有用.但是,我想知道为什么Rails不会预先计算最终的签名URL并将其嵌入到HTML页面中.通过这种方式,我们可以保留签名URL/受保护文件的优点,而无需对Rails服务器进行N次额外的调用.

I know that the redirect is useful for signed URLs. However I wonder why Rails does not precompute the final signed URL and embed that into the HTML page... In this way we could keep the advantages of signed URLs / protected files, without making N additional calls to the Rails server.

是否可以在HTML中直接包含图像变体的最终URL/预签名URL(从而避免重定向)?否则,为什么那不可能呢?

Is it possible to include the final URL / pre-signed URL of image variants directly in the HTML (thus avoiding the redirect)? Otherwise, why is that impossible?

推荐答案

经过几天的推理和测试,我对最终的解决方案感到非常兴奋,下面将对此进行解释.这是一种自以为是的图像处理方法,可能并不代表当前的Rails Way™️,但是对于提供许多公共图像的网站而言,它具有难以置信的优势,尤其是:

After days of reasoning and tests, I am really excited of my final solution, which I explain below. This is an opinionated approach to images and may not represent the current Rails Way™️, however it has incredible advantages for websites that serve many public images, in particular:

  1. 当您为一个包含N张图片的页面提供服务时,您不会收到对应用服务器的1个+ N个请求,相反,您对该页面只收到1个请求
  2. 通过CDN提供图像,这可以缩短加载时间
  3. 存储桶不是完全公开的,而是受Cloudflare保护的
  4. Cloudflare缓存了图像,这大大减少了您的S3账单
  5. 您将API请求(即存在)的数量大大减少到S3
  6. 此解决方案不需要对Rails进行大的更改,因此在出现问题时可以直接切换回Rails的默认行为
  1. When you serve a page with N images you don't get 1 + N requests to your app server, instead you get only 1 request for the page
  2. The images are served through a CDN and this improves the loading time
  3. The bucket is not completely public, instead it is protected by Cloudflare
  4. The images are cached by Cloudflare, which greatly reduce your S3 bill
  5. You greatly reduce the number of API requests (i.e. exists) to S3
  6. This solution does not require large changes to Rails, and thus it is straightforward to switch back to Rails default behavior in case of problems

这是解决方案:

  1. 创建一个s3存储桶并将其配置为
  2. 在您的Rails应用程序中,您可以继续使用私有存储/acl,这是默认的Rails行为
  3. 每次更新或创建@post后,在您的Rails应用程序中调用@post.variant(...).processed;然后在您的视图中使用'https://storage.example.com/' + @post.variant(...).key'(请注意,为了避免在s3中进行其他检查,我们在视图中不会在此处调用processed);您还可以有一个rake任务,在每个对象上调用processed,以防您需要重新生成变体.如果您很少更改一些变体(例如,每个帖子1张图片/变体),这将是完美的选择
  1. Create an s3 bucket and configure it to host a public website (i.e. call it storage.example.com) - you can even disable the public access at bucket level and allow access only to the Cloudflare ips using a bucket policy
  2. Go to Cloudflare and configure a CNAME for storage.example.com that points to your domain; you need to use Flexible SSL (you can use a page rule for the subdomain); use page rules to set heavy caching: set Cache Everything and set a very long value (e.g. 1 year) for Browser Cache TTL and Edge Cache TTL
  3. In you Rails application you can keep using private storage / acl, which is the default Rails behavior
  4. In your Rails application call @post.variant(...).processed after every update or creation of @post; then in your views use 'https://storage.example.com/' + @post.variant(...).key' (note that we don't call processed here in the views to avoid additional checks in s3); you can also have a rake task that calls processed on each object, in case you need to regenerate the variants; this is works perfectly if you have only a few variants (e.g. 1 image / variant per post) that are changed infrequently

以上大多数步骤都是可选步骤,因此您可以根据需要将它们组合在一起.

Most of the above steps are optional, so you can combine them based on your needs.

这篇关于Rails ActiveStorage:如何避免每个映像进行一次重定向?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆