使用 AWS Cloudfront 避免 CORS,并清理 SPA url

Posted

技术标签:

【中文标题】使用 AWS Cloudfront 避免 CORS,并清理 SPA url【英文标题】:Avoid CORS with AWS Cloudfront, and clean SPA urls 【发布时间】:2019-02-17 17:33:39 【问题描述】:

我有一个位于 S3 中的单页应用程序,前面是 Cloudfront。还有一个 SPA 通过 AJAX 请求与之对话的后端。我正在尝试两者:

    拥有干净的 URL (a la https://keita.blog/2015/11/24/hosting-a-single-page-app-on-s3-with-proper-urls/),通过要求 cloudfront 将 403 和 404 错误重写为生成索引页面的 200 个错误, 通过将云端行为添加到代理 /api/* 到服务器(如 https://***.com/a/42883221/1586229)来避免 CORS 问题。

是否有可能实现这两个?问题是,cloudfront 甚至会将来自 api 的 403 和 404 更改为 200 index.html 响应。

如果这无法完成,您能否推荐另一种方法来完成我正在尝试做的事情?

【问题讨论】:

【参考方案1】:

这种行为可以通过 Lambda@Edge 来完成。这是计划:

创建一个将在 Origin Request 上触发的 Lambda 函数(参见图表了解生命周期的位置)。请务必在 us-east-1 中创建它,因为这是唯一可以定义 Lambda@Edge 中使用的 Lambda 的区域。

该函数有以下工作:将/login/profile/anything_other_than_assets 等路径的请求重写为/index.html。对我来说,我能够制定规则:

如果有扩展名,它就是资产。否则就是路径

希望您可以这样做或类似。这是我的函数体的外观(我使用了节点 8)

const path = require('path')

exports.handler = (evt, ctx, cb) => 
    const request = evt.Records[0].cf

    if (!path.extname(request.uri)) 
        request.uri = '/index.html'
    

    cb(null, request)

确保您“发布新版本”,然后复制 arn(位于页面顶部)

将其粘贴到 S3 源行为的“Lambda 函数关联”部分。

由于 Lambda@Edge 函数关联的范围为 Origin 级别,因此此重定向行为不会影响您的 /api/* 行为。

确保删除自定义错误处理程序。您的 S3 行为不再需要它们,您的 api 行为也不需要它们。

【讨论】:

以上是关于使用 AWS Cloudfront 避免 CORS,并清理 SPA url的主要内容,如果未能解决你的问题,请参考以下文章

使用 AWS Lambda、S3 和 Cloudfront 付款和 Stripe Checkout 的 CORS 问题

hls.js CORS 使用 AWS Cloudfront 的 Cookie 问题

没有 S3 存储桶的 AWS Cloudfront CORS 标头

AWS CloudFront 签名 Cookie CORS 问题

AWS - Cloudfront、S3 和 W3TotalCache 的 CORS 标头失败

从浏览器缓存提供图像时,AWS S3 + CloudFront 会出现 CORS 错误