默认根对象

如果您定义默认根对象,最终用户对分配的子目录的请求不返回默认根对象。例如,假设 index.html 是您的默认根对象且 CloudFront 接收最终用户对 CloudFront 分配下的 install 目录的请求:

https://d111111abcdef8.cloudfront.net/install/

CloudFront 不会返回默认根对象,即使 index.html 的副本出现在install目录中。

此时一个空资源作为文件被下载下来

这与我们常用的nginx目录访问明显的不同


实现与nginx类似的行为

以下示例函数会将 index.html 附加到不在 URL 中包含文件名或扩展名的请求中。此函数对于托管在 Amazon S3 存储桶中的单页应用程序或静态生成的网站非常有用。

在 GitHub 上查看此示例

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 中的实际文件存储在 /blog/index.html。为了让 CloudFront 将请求定向到 S3 中的正确文件,您需要在从 S3 获取文件之前将 URL 重写为 www.example.com/blog/index.html。此函数拦截对 CloudFront 的传入请求并检查是否存在文件名和扩展名。如果没有文件名和扩展名,或者 URI 以“/”结尾,则函数会将 index.html 附加到 URI。

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

参考将查看器重定向到新的 URL

Last modified: April 22, 2025

Author

Comments

Write a Reply or Comment

Your email address will not be published.