我在AWS中有当前配置:
S3 Bucket设置为静态网站的前端
后台有一个EC2实例的ELB
Cloudfront distribution with two origin, two behavior, and two custom error page
- 的起源:
- S3 Bucket(静态网站)
- dev-api.mydomain.com(下面提到的指向ELB的别名记录)
- 行为:
- "/api/*";到dev-api.mydomain.com的路由
- "*";到S3的路由
- 错误页面(这部分是对我的问题最重要的):
- 403返回200响应index.html(来自S3)
- 404返回200响应index.html(来自S3)
- 的起源:
Route53:
注册域名- <
- dev.mydomain.com指向cloudfront分布/gh>
- dev-api.mydomain.com指向ELB
如何区分从S3和后端服务器返回的403和404错误?
注意:我使用react路由器来处理静态网站中的所有路由,所以每个请求S3都会从S3返回404,除非用户特别要求/index.html资源。
场景1:当用户访问dev.mydomain.com/logi(拼写错误的登录)时,我希望它会击中我的S3桶并返回404,然后获取桶中的index.html文件。Cloudfront将返回带有200 OK状态的index.html文件,我的应用程序将通过显示404页面来处理无效路由。
场景2:当用户访问dev.mydomain.com/login时,它将击中我的S3存储桶,返回404并返回index.html文件。在进入登录页面后,为了这个示例,我向dev.mydomain.com/api/non_existant_route发出了一个网络请求。我希望它击中我的API服务器并返回404,然后我的前端将通过显示有关API请求失败的错误消息来处理。
然而,在场景2中发生的事情是从我的后端服务器返回404到Cloudfront,然后返回index.html文件(来自S3)作为响应,状态码为200。
所以,我的问题是-是否有可能配置Cloudfront返回不同的错误页面基于发送回错误代码的起源?如果没有,如何才能为后端服务器返回正确的响应?
是否需要我重新构建AWS解决方案?
通过从cloudfront中删除自定义错误响应,我能够解决403和404问题。
我在默认行为(*)上创建了一个Lambda@Edge函数,它路由到我的S3桶。在Origin Request中,该函数将对/login等页面的请求修改为从桶返回/index.html。
另一个方法是:
- 在S3上打开静态Web托管
- 替换S3 bucket名称与S3 CloudFront起源静态网站URL。
- 从CloudFront删除错误页面。
错误页面将由各自的起源而不是CloudFront处理。
在我的情况下,我也有两个起源,都是一个页面的应用程序(OPA),所以都包含index.js
- React App(负责我的主要应用)通过S3静态网站托管。(企业社会责任构建)
- Webflow应用程序(产品信息和博客等静态网站)
我们的react应用基于路由有许多不同的行为(应用需要),所以我将Webflow配置为默认行为。
首先,我为404
添加了自定义错误处理,将页面路径重定向到/index.js
和HTTP状态200
,因为许多应用程序路由不直接存在于S3 Website
中并导致404(这是许多技术博客建议的,在单一来源的情况下工作得很好)
但是一旦我添加Webflow网站原点作为我的Default(*)
行为,每当404
发生在React应用程序中,它将被重定向到默认行为/index.js
(我们的静态产品信息网站)
最后,我删除了所有自定义错误处理,它将开始按预期工作。所有的React路由都被重定向到React行为,而不匹配的行为路由将被重定向到Default(*)
Webflow网站。