使用 Cloudfront 从自定义域 url 中删除 stage

Posted

技术标签:

【中文标题】使用 Cloudfront 从自定义域 url 中删除 stage【英文标题】:Use Cloudfront to remove stage from custom domain url使用 Cloudfront 从自定义域 url 中删除 stage 【发布时间】:2021-11-28 21:57:54 【问题描述】:

我有一个烧瓶应用程序通过 zappa 部署到 AWS Lambda。 Zappa 创建了一个 AWS 休息端点,例如 random_api_ID.execute-api.us-east-2.amazonaws.com/dev,当直接输入浏览器时,它可以完美运行。但是,当我使用 Cloudfront 将此端点关联到我的自定义域 dev.mywebsite.com 时,对于存储在子文件夹中的任何资产,我都会在响应中收到 404 错误。原因是因为 Cloudfront 正在提供诸如

之类的 url

dev.mywebsite.com/dev/static/css/style.css

而不是

dev.mywebsite.com/static/css/style.css

另外,这有效:random_api_ID.execute-api.us-east-2.amazonaws.com/dev/static/css/style.css

但这不是:random_api_ID.execute-api.us-east-2.amazonaws.com/static/css/style.css

所以,不知何故,我需要 Cloudfront 将 random_api_ID.execute-api.us-east-2.amazonaws.com/devdev.mywebsite.com 关联,而不是 dev.mywebsite.com/dev

我的 Cloudfront 发行版具有以下参数:

 Alternate Domain Name: dev.mywebsite.com 
 Origin Domain: random_api_ID.execute-api.us-east-2.amazonaws.com
 Origin Path: dev <-- this is the stage name

我尝试通过 AWS API Gateway 将自定义域映射到 zappa 生成的 AWS 休息端点;但是,该解决方案会生成一个我无法控制的私有 Cloudfront 域;我更喜欢涉及配置 Cloudfront 的解决方案。

提前致谢!

【问题讨论】:

【参考方案1】:

您可以选择添加您的stageName 以使您的网址在没有它的情况下也可以访问。

参考:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesOriginPath

转到您的 CloudFront 的分发版,编辑指向 API 网关 URL 的 Origin

找到Origin path 选项 将您的stageName 放入其中(我的示例是dev 阶段)所以它应该是/dev(需要在前缀有/

然后点击保存更改,等待部署大约 5 分钟。并尝试以您喜欢的方式访问它

https://<domainName>/<resourceName>

【讨论】:

我的舞台名称也称为dev,当我在origin path 字段中输入它时,Cloudfront 会提供带有dev 附加到根目录的url。当我将 origin path 留空时,浏览器无法加载没有舞台名称的 url。什么可能导致我们得到不同的结果? 另外,我注意到在您的origin path 字段中,您输入了dev 而不是/dev。当我在没有正斜杠的字段中输入我的舞台名称并尝试保存我的更改时,Cloudfront 返回错误 Failed to create origin: The parameter originPath contains one or more parameters that are not valid.。我错过了什么? 当您将源路径留空时,它只会在您的 CloudFront DNS 与您的 API DNS 之间进行映射,因此如果您想访问您的开发阶段,CloudFront DNS 需要具有 /dev .所以如果我们添加源路径,我们就不需要添加那个 /dev 了。 您的评论 so if you want to access your dev stage, the CloudFront DNS needs to have &lt;cloudfront-dns&gt;/dev. So if we add the origin path, we no need to add that /dev right,我需要 cloudfront-dns 以包含带有舞台名称的 api-dns。换句话说:cloudfront_dns = api_dns/stage。但是,当在origin-path 中添加stage 时,Cloudfront 似乎会产生cloudfront_dns/stage = api_dns/stage 是的,如果您使用Origin Path,它可以帮助您隐藏添加stage而无需将其输入到域名中。啊等等,在检查了我的原始路径之后,它应该有 / at 前缀。对不起,我的困惑^^【参考方案2】:

我找到了这个article 并最终通过使用 Cloudfront Functions 解决了这个问题:

    确保您有一个 Cloudfront 分配,它 a) 与您的 AWS API Gateway 端点关联,并且 b) 包含您的自定义域名。

    在您分配的 origin 选项卡中,我输入了完整的 AWS API 网关端点。我的应用程序使用 Zappa 自动生成的端点random_api_ID.execute-api.us-east-2.amazonaws.com/dev。在origin domain 字段中输入完整的端点应该 使用\dev 自动填充origin path 字段。

    在 Cloudfront 导航窗格中,选择 Functions,然后单击 Create function 按钮。

    输入函数名称,然后点击Create Function

    选中Build tab 后,转到Function Code 部分并输入以下javascript

    function handler(event) 
        var request = event.request;
        request.uri = request.uri.replace(/^\/[^/]*\//, "/"); 
        return request;
    
    

    保存你的函数

    通过单击Test 选项卡并输入带有附加阶段名称的 url 来测试您的功能:

    单击test function 按钮。您应该在函数代码下方收到一条成功执行消息:

    单击Publish 选项卡并通过单击Publish function 按钮发布您的函数。

    在发布部分下,您需要将发布的函数与您的 Cloudfront 发行版相关联。点击Add distribution按钮。

    在新窗口中,选择一个分布并单击Add Association 按钮。

    等待 Cloudfront 完成部署您的发行版。完成后,在浏览器中检查您的自定义域并确保资产已成功加载。

【讨论】:

以上是关于使用 Cloudfront 从自定义域 url 中删除 stage的主要内容,如果未能解决你的问题,请参考以下文章

使用 AWS CloudFront 时,如何向公众隐藏自定义源服务器?

从自定义相册 PHPhotoLibrary 目标 C 中删除图像

Django Ajax 403 仅在从自定义 localhost url 发布时

用于访问无法从自定义域访问的 S3 私有内容的签名 URL

Cloudfront 自定义源分发返回 502“错误无法满足请求。”对于某些 URL

从自定义域使用反向代理和 SSL 访问 Service Fabric