如何在Cloudfront上的静态托管网站上为子目录设置默认根对象?具体来说,每当用户要求 www.example.com/subdir
时,我都希望提供 www.example.com/subdir/index.html
. 注意,这是用于提供在S3存储桶中保存的静态网站 . 此外,我想使用原始访问标识将对S3存储桶的访问限制为仅限Cloudfront .
现在,我知道Cloudfront的工作方式不同于S3和亚马逊国家specifically:
CloudFront默认根对象的行为与Amazon S3索引文档的行为不同 . 将Amazon S3存储桶配置为网站并指定索引文档时,即使用户请求存储桶中的子目录,Amazon S3也会返回索引文档 . (索引文档的副本必须出现在每个子目录中 . )有关将Amazon S3存储桶配置为网站和索引文档的更多信息,请参阅Amazon Simple Storage Service开发人员指南中的Amazon S3上的主机网站章节 .
因此,即使Cloudfront允许我们指定默认根对象,这仅适用于 www.example.com
而不适用于 www.example.com/subdir
. 为了解决这个难题,我们可以将原始域名更改为指向S3给出的网站 endpoints . 这很好用,可以统一指定根对象 . 不幸的是,这似乎与origin access identities不相容 . 具体来说,以上链接指出:
更改为编辑模式:Web分布 - 单击“起源”选项卡,单击要编辑的原点,然后单击“编辑” . 您只能为Origin Type为S3 Origin的原点创建原始访问标识 .
基本上,为了设置正确的默认根对象,我们使用S3网站 endpoints 而不是网站存储桶本身 . 这与使用原始访问标识不兼容 . 因此,我的问题归结为两者
-
是否可以为Cloudfront上的静态托管网站的所有子目录指定默认根对象?
-
是否可以为从Cloudfront提供的内容设置原始访问标识,其中源是S3网站 endpoints 而不是S3存储桶?
8 回答
有 IS 这样做的方法 . 而不是通过在下拉列表中选择它(www.example.com.s3.amazonaws.com)将其指向您的桶,将其指向您的桶的静态域(例如www.example.com.s3- website-us -west-2.amazonaws.com):
感谢This AWS Forum thread
UPDATE: It looks like I was incorrect! See JBaczuk's answer, which should be the accepted answer on this thread.
不幸的是,你的两个问题的答案都是否定的 .
1. Is it possible to specify a default root object for all subdirectories for a statically hosted website on Cloudfront?
没有 . 如_1434210中所述......
2. Is it possible to setup an origin access identity for content served from Cloudfront where the origin is an S3 website endpoint and not an S3 bucket?
不是直接的 . 您对CloudFront的起源选项是S3存储桶或您自己的服务器 .
然而,第二个选项确实开辟了一些有趣的可能性 . 这可能会破坏您尝试执行的操作的目的,但您可以设置自己的服务器,其唯一的工作是成为CloudFront原始服务器 .
当http://d111111abcdef8.cloudfront.net/install/的请求进入时,CloudFront会将此请求转发到您的源服务器,要求
/install
. 您可以根据需要配置源服务器,包括在这种情况下提供index.html
.或者你可以写一个小的网络应用程序,只需接听这个电话,无论如何直接从S3获取 .
但我意识到,设置自己的服务器并担心扩展它可能会破坏你首先尝试做的目的 .
激活S3托管意味着你必须向全世界打开桶 . 在我的情况下,我需要保持桶专用并使用原始访问标识功能仅限制对Cloudfront的访问 . 像@Juissi建议的那样,Lambda函数可以修复重定向:
发布功能后,请转至AWS控制台中的cloudfront分发 . 转到
Behaviors
,然后在Lambda Function Associations
下选择Origin Request
,最后将ARN粘贴到新功能中 .还有另一种方法可以在子目录中提供默认文件,例如
example.com/subdir/
. 实际上,您可以(以编程方式)存储文件夹中的密钥subdir/
. 此文件将显示在S3管理控制台中,但实际上存在,CloudFront将为其提供服务 .该问题的解决方法是使用lambda @ edge重写请求 . 只需要为CloudFront分配的查看者请求事件设置lambda,并用默认根文档重写以'/'结尾的所有内容,并且不等于'/',例如index.html的 .
我知道这是一个老问题,但我自己也在努力解决这个问题 . 最终,我的目标不是在目录中设置默认文件,而是更多地获得在文件末尾没有
.html
的情况下提供文件的最终结果我最终从文件名中删除
.html
并以编程方式/手动将mime类型设置为text/html
. 它不是传统的方式,但它似乎确实有效,并且在不牺牲cloudformation的好处的情况下满足了我对漂亮网址的要求 . 设置mime类型很烦人,但在我看来支付小费用的好处有一个"official" guide published on AWS blog建议设置由CloudFront分配触发的Lambda @ Edge功能:
按照上面链接的指南查看设置此步骤所需的所有步骤,包括S3存储桶,CloudFront分配和Lambda@Edge功能创建 .
使用lambda @ edge的另一种方法是使用CloudFront的错误页面 . 设置Custom Error Response将所有403发送到特定文件 . 然后将javascript添加到该文件以将index.html附加到以/结尾的URL . 示例代码: