如何在AWS Cloudfront(S3)上获取干净的URL?

时间:2017-03-11 23:19:03

标签: amazon-web-services amazon-s3 amazon-cloudfront

我在AWS S3上托管我的静态网站,将Cloudfront作为CDN,我想知道如何让干净的URL工作。

我目前必须转到example.com/about.html才能获得该页面。我更喜欢example.com/about以及其他所有页面。此外,我有必要这样做,因为我的规范网址已经设置了元标记和搜索引擎,并且要改变它们会有点多。

Cloudfront中是否有我无法看到的设置?

更新

我已经探讨了两种选择,其中一项由Matt详述。

首先是在上传到S3之前修剪.html文件,然后在http中编辑该文件的内容标题。这可能会很漂亮,但我无法弄清楚如何从命令行编辑内容标题,我在那里编写了我的"推送网站更新" bash脚本。

第二个是由Matt在下面详细说明并利用S3的功能来识别根默认文件,通常是index.html。可能是一个很好的方法,但它使我的本地测试具有挑战性,并且它在URL上留下了一个斜杠,这对我来说并不起作用。

4 个答案:

答案 0 :(得分:2)

当您在S3(以及扩展CloudFront)中托管您的网站时,您可以将S3配置为在请求目录时加载“默认”文件。这被称为“索引文档”。

例如,您可以将S3配置为加载index.html作为默认文件。这样,如果请求是example.com/abc/,则会加载abc/index.html

执行此操作时,如果他们请求example.com/abc/123.html,则会提供abc/123.html。因此,默认文件仅在请求文件夹时适用。

要解决您对example.com/about/的请求,您可以使用默认文件index.html配置您的存储分区,并将about/index.html放入您的存储区。

更多信息可以在亚马逊的文档中找到:Index Document Support

答案 1 :(得分:1)

尝试 AWS Lamda@Edge。彻底解决了这个问题。

首先,创建一个 AWS Lambda 函数,然后附加您的 CloudFront 作为触发器。

在此 AWS Lamda 页面的代码部分,在下面的存储库中添加代码段。

https://github.com/CloudUnder/lambda-edge-nice-urls/blob/master/lambdaRewrite.js

注意存储库自述部分中的选项

答案 2 :(得分:0)

在将S3存储桶配置为网站端点以及Cloudfront分发时,您可以使用自定义来源来克服丑陋的网址。缺点是您无法将Cloudfront配置为使用HTTPS在Cloudfront和您的来源之间进行通信。您仍然可以使用HTTPS,但不能使用端到端加密。

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-https-cloudfront-to-s3-origin.html

答案 3 :(得分:0)

您可以将Lambda用作网站的反向代理。

在API网关中,您需要使用资源路径=“ {proxy +}”创建一个“代理资源”

然后,创建一个Lambda函数来路由请求:

const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const myBucket = 'myBucket';

exports.handler = async (event) => {

    var responseBody = "";

    if (event.path=="/") {
        responseBody = "<h1>My Landing Page</h1>";
        responseBody += "<a href='/about'>link to about page</a>";
        return buildResponse(200, responseBody);
    }

    if (event.path == "/about") {

        var params = { 
            Bucket: myBucket,
            Key: 'path/to/about.html',
        };

        const data = await s3.getObject(params).promise();

        return buildResponse(200, data.Body.toString('utf-8'));
    }

    return buildResponse(404, 'Page Not Found');

};


function buildResponse(statusCode, responseBody) {

    var response = {
        "isBase64Encoded": false,
        "statusCode": statusCode,
        "headers": {
            "Content-Type" : "text/html; charset=utf-8"
        },
        "body": responseBody,
    };

    return response;
}

然后,您可以使用自定义域为API网关创建CloudFront分配。

有关更多详细信息,请检查以下答案: https://stackoverflow.com/a/57913763/2444386