You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让CloudFront为SPA所有路由提供缓存的index.html

问题:CloudFront 托管SPA的路由缓存优化问题

架构与现状

  • SPA通过CloudFront分发,源站为S3存储桶
  • 访问根域名https://example.com时响应正常,首字节响应时间50ms
  • 访问带路由的URL(如https://example.com/route1)时,CloudFront会出现缓存未命中:先尝试在S3查找对应路由,收到404后才返回默认的index.html,首字节响应时间长达0.5-1秒

需求

实现所有非根路由均返回缓存的index.html,达到https://app.clickup.com的效果——任意路由都能以50ms左右的缓存命中响应。

已尝试方案

使用viewer-request类型的CloudFront函数重写请求URI,但响应时间仍在150-200ms,未达预期。函数代码如下:

function handler(event) {
  var request = event.request;
  var uri = request.uri;
  
  if (!uri.includes('.')) { // 对静态js、css或图片资源保留默认行为
      request.uri = '/index.html';
  }
  
  return request;
}

测试命令:

curl -w "\nDNS Lookup: %{time_namelookup}s\nTCP Connect: %{time_connect}s\nTLS Handshake: %{time_appconnect}s\nFirst Byte: %{time_starttransfer}s\nTotal Time: %{time_total}s\n" -o /dev/null -s https://app.clickup.com/bla

解决方案

1. 调整CloudFront缓存策略,统一缓存键

当前函数已将非静态资源请求重写为/index.html,但如果缓存键仍基于原始请求URI,会导致每个路由生成独立缓存条目,无法共享根路径的缓存。需修改缓存策略:

  • 进入CloudFront控制台,找到目标分发
  • 切换到「缓存策略」标签,创建或修改缓存策略
  • 在「缓存键和源请求」中,设置缓存键仅基于重写后的/index.html URI(或直接指定固定缓存键如spa-index)
  • 为静态资源(带后缀的文件)配置单独的缓存行为,保留原始URI作为缓存键

2. 优化CloudFront函数逻辑

原函数的!uri.includes('.')判断不够严谨,可能误重写API类路径,建议调整为仅针对SPA前端路由:

function handler(event) {
  const request = event.request;
  const uri = request.uri;
  
  // 排除API路径、静态资源,仅重写SPA路由
  if (!uri.startsWith('/api') && !uri.includes('.') && uri !== '/') {
      request.uri = '/index.html';
  }
  
  return request;
}

确保函数关联到所有需要重写的缓存行为,且在viewer-request阶段执行(此阶段修改URI后,缓存会基于修改后的URI生成)

3. 配置S3静态网站托管错误页面兜底

即使使用CloudFront函数,仍建议配置S3的错误页面作为兜底:

  • 进入S3控制台,找到目标存储桶
  • 开启「静态网站托管」,设置「错误文档」为index.html
  • 避免CloudFront函数异常时,用户收到S3的404响应

4. 预热CloudFront缓存

完成配置后,主动预热/index.html的缓存:

  • 使用CloudFront的「缓存失效」工具,提交/index.html的失效请求(或直接用curl请求一次,触发边缘节点缓存该文件)
  • 确保所有重写后的请求都能直接命中边缘节点缓存,达到50ms左右的响应速度

内容的提问来源于stack exchange,提问作者Daniel Birowsky Popeski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:35:04