从 S3 cloudfront 静态网站重定向中删除根 /

Out*_*all 2 amazon-s3 amazon-cloudfront

我有一个指向不同域的静态 S3 网站: https://www.externaldomain.com/id12345

此 S3 分配给 CloudFront,然后将其分配给 A 记录以 mydomain.com

结果是,当我导航到mydomain.com它时,它会将访问者重定向到https://www.externaldomain.com/id12345

一切工作正常,除了它重定向到https://www.externaldomain.com/id12345//

我怎样才能让它在https://www.externaldomain.com/id12345没有/ 的情况下完全重定向到

我无法控制externaldomain.com它,当包含/时它会给出 404 。

Mic*_*bot 7

当您选择将所有请求重定向到另一个主机的选项时,S3 假定您希望在新 URL 的末尾保留原始请求路径。请求 URI 始终以 开头/,因此当 S3 将传入的请求 URI 附加到您在生成重定向时提供的路径时,最后是/来自您的请求。S3 并没有添加它,而是从传入的请求 URI 中复制它。

因此,这种行为乍一看令人困惑,但并非不正确。

你在评论中说你想做的是,不管走哪条路,扔掉它。所有请求都转到目标服务上的单个路径。

为此,请使用路由规则。选择“Use this bucket to host a web site”,然后为索引文档命名——对于这个用例,您实际上并不需要一个名称,但该字段不是可选的,因此只需输入index.html。然后,添加如下所示的重定向规则:

<RoutingRules>
  <RoutingRule>
    <Condition>
        <KeyPrefixEquals></KeyPrefixEquals> <!-- empty string matches all requests -->
     </Condition>
    <Redirect>
        <Protocol>https</Protocol>
        <HostName>other-site.example.com</HostName>
        <ReplaceKeyWith>12345</ReplaceKeyWith> <!-- new path, with *no* leading slash -->
    </Redirect>
  </RoutingRule>
</RoutingRules>  
Run Code Online (Sandbox Code Playgroud)

有关路由规则语法的更多信息,请参阅S3 开发人员指南中的高级条件重定向

文档没有提到使用空<KeyPrefixEquals>来匹配所有请求,但这是有效的,因为您要求测试的规则是 (pseudocode) left(key,0) == '',这当然总是正确的。

同样不明确的是,按照惯例,S3 对象键不以/(从/概念上讲,HTTP 中使用的前导是在对象键的第一个字符之前)开始。这就是为什么<ReplaceKeyWith>和任何其他关键参考不需要(也不应该有)/重定向路由规则的前导。


最佳实践建议您忽略以下供您考虑的替代解决方案。它在很多方面都很可怕,很笨拙,而且是错误的,但它应该适用于许多应用程序......

使用“重定向请求”选项,就像您最初所做的那样,但放在#您提供的路径的末尾。然后 S3 重定向到,https://example.com/12345#/或者更准确地说,https://example.com/12345#${original_uri}. 因为#标记了 URI 片段的开始,所以它不会发送到目标服务器,所以它也应该做你想做的,尽管它可能与 SPA 路由器交互,如果这是你正在使用的。