默认根对象
如果您定义默认根对象,最终用户对分配的子目录的请求不返回默认根对象。例如,假设 index.html
是您的默认根对象且 CloudFront 接收最终用户对 CloudFront 分配下的 install
目录的请求:
https://d111111abcdef8.cloudfront.net/install/
CloudFront 不会返回默认根对象,即使 index.html
的副本出现在install
目录中。
此时一个空资源作为文件被下载下来
这与我们常用的nginx目录访问明显的不同
实现与nginx类似的行为
以下示例函数会将 index.html
附加到不在 URL 中包含文件名或扩展名的请求中。此函数对于托管在 Amazon S3 存储桶中的单页应用程序或静态生成的网站非常有用。
function handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith('/')) {
request.uri += 'index.html';
}
// Check whether the URI is missing a file extension.
else if (!uri.includes('.')) {
request.uri += '/index.html';
}
return request;
}
例如,如果用户访问 www.example.com/blog,则 S3 中的实际文件存储在
CloudFront 中有一个称为默认根对象的功能,允许您指定仅适用于根对象而不适用于任何子文件夹的索引文档。例如,如果您将 index.html 设置为默认根对象并且用户访问 www.example.com,CloudFront 会自动将请求重写为 www.example.com/index.html。但是,如果用户访问 www.example.com/blog,则此请求不再位于根目录中,因此 CloudFront 不会重写此 URL,而是按原样将其发送到源。此函数处理根目录和所有子文件夹的 URL 重写。因此,您在使用此功能时无需在 CloudFront 中设置默认根对象(尽管设置它并没有什么坏处)
注意:如果您使用的是 S3 静态网站托管,则不需要使用此功能。 S3 静态网站托管允许您设置索引文档。索引文档是当任何请求缺少文件名时 Amazon S3 返回的网页,无论它是针对网站的根目录还是子文件夹。此 Amazon S3 功能执行与此功能相同的操作。
真正实现与nginx同样的行为
上面实现了nginx的行为吗?并没有真正的实现,对于单页面应用它是可以的,但是对于更丰富的资源它无法正确的处理访问的path
nginx的目录访问行为 :例如http://www.abc.com/abc
,这时服务器会搜索网站根目录下有没有名为abc
的文件或目录,如果为目录,服务器将返回301重定向,浏览器再使用http://www.abc.com/abc/
访问
而上面函数的行为: 例如http://www.abc.com/abc
,这时cloudfront函数直接修改请求为http://www.abc.com/abc/index.html
得到资源并返回
看到与上面的区别了吗?访问nginx服务器浏览器发起了第二次的请求,所以其相对路径为/abc/ , 而对于cloudfront,浏览器会一直认为在 ‘/’ 下,所以它们后继发起的请求uri是不一样的。
function handler(event) {
var request = event.request;
var headers = request.headers;
var host = request.headers.host.value;
var uri = request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith('/')) {
request.uri += 'index.html';
}
// Check whether the URI is missing a file extension.
else if (!uri.includes('.')) {
var newuri = uri + '/'
var newurl = `https://${host}${newuri}` // Change the redirect URL to your choice
//var newurl = request.url + '/index.html'
var response = {
statusCode: 301,
statusDescription: 'Found',
headers:
{ "location": { "value": newurl } }
}
return response;
}
return request;
}
当url的path访问为目录且不是以’/’结尾的时候,直接返回浏览器 response 301
Comments