【问题标题】:Stop Cloudflare from caching redirects阻止 Cloudflare 缓存重定向
【发布时间】:2017-05-30 19:19:48
【问题描述】:

我这里有点特殊的情况。

我们有一个域托管用户上传的媒体(已应用图像操作)(usermedia.com)。媒体存储在 Amazon S3 存储桶中,Cloudflare 位于该存储桶的前面。

如果用户请求图片,他们可能会浏览到https://usermedia.com/my-image-resize-200-200.jpg

如果该图像存在,则提供该图像,否则 Amazon S3 会执行 302 重定向(通过路由规则)到 https://app.com/generate/my-image-resize-200-200.jpg,这会生成调整大小的图像,将其上传到 S3,然后再次重定向回 https://usermedia.com/my-image-resize-200-200.jpg。这次文件存在于 S3 中并被提供。

问题是当我们启用 Cloudflare 代理时 - 它会缓存重定向,因此如果媒体不存在,Cloudflare 就会陷入连续的重定向周期。我尝试使用 307 重定向,但问题仍然存在。

任何想法如何解决这个问题?

【问题讨论】:

  • 您确定问题出在 CloudFlare 而不是您的浏览器或亚马逊吗?我已经在站点中构建了一个精确的功能,但在它的服务器上而不是在 AS3 上。 CloudFlare 处理得很好。对图像的下一次调用几乎会立即加载它。
  • 我使用 CloudFront 而不是 Cloudflare 进行了类似的“未找到时重定向”设置,但我使用 CloudFront > HAProxy (EC2) > S3。 HAProxy 将 403 更改为 302,设置Location:,并设置Cache-Control: no-cache, no-store 来解决这个问题......位置实际上没有改变,除了添加了一个查询字符串来指示调整大小操作,HAProxy 将这些发送到调整大小服务器。然后调整大小实际上保存到 S3 但不重定向 - 它只是返回图像,以避免潜在的 S3 最终一致性问题。但我会回顾一下我关于重定向规则的笔记。
  • @Jules 提出了一个很好的观点。在一种情况下,S3 在新对象创建方面最终是一致的:如果您在创建对象之前已经执行了 GET,并且您按照设计这样做了。
  • @Jules 我很确定它是 Cloudflare,因为当我关闭 Cloudflare 代理时它可以正常工作(除了 Cloudflare 不缓存图像等,所以毫无意义)。
  • 您应该在 cf 中设置一个页面规则,以从不缓存或优化这些图像 - 希望在您可以通配符的目录中。看看问题是否仍然存在。

标签: redirect amazon-s3 cloudflare


【解决方案1】:

目前我看到 Cloudflare 不缓存 307 重定向。第一个查询:

第二次查询:

您可以像这样在 S3 重定向规则中设置响应代码:

<RoutingRules>
  <RoutingRule>
  <Condition>
    <HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals>
  </Condition>
  <Redirect>
    <HostName>app.com</HostName>
    <HttpRedirectCode>307</HttpRedirectCode>
  </Redirect>
  </RoutingRule>
</RoutingRules>

【讨论】:

    【解决方案2】:

    我有完全相同的设置和一些问题。我发现问题确实是clouldflare。当图像不存在时,S3 返回一个指向调整大小端点的 307,这里的问题是 cloudflare 添加了缓存标头(例如:cache-control:public,max-age=691200)因为可能你有缓存选项卡浏览器缓存过期设置,因此当浏览器收到响应时,它将缓存它(因为存在缓存控制标头),因此下一个请求将从浏览器缓存中提供。

    更新:

    快速解决方案可能很简单。在 cloudflare 上将 Browser Cache Expiration 设置为“Respect Existing Headers”,这样 cloudflare 将不会添加使浏览器缓存响应的标头。如果您仍然希望在本地缓存图像,只需在从调整大小脚本创建 S3 图像时直接在 S3 图像上设置缓存控制标头

    S3.putObject({
        Body: buffer,
        Bucket: BUCKET,
        ContentType: 'image/jpeg',
        CacheControl: 'max-age=604800',
        Key: finalKey,
    })
    

    如果您有其他资产(例如 css 或 javascript 等),您也可以从 aws 控制台为它们设置 CacheControl 标头,或者,如果您将它们放在某个文件夹中,比如说“foo”,您可以去到 Cloudflare,创建页面规则并指示为“foo”文件夹下的所有文件设置浏览器缓存 TTL。

    我知道这是一个迟到的答案,但希望能帮助将来遇到同样问题的人

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-30
      • 1970-01-01
      • 2013-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多