部署到Amazon CloudFront后Next.js静态路由路径失效的解决方法
解决Next.js静态路由在CloudFront下的404问题
问题核心原因:Next.js静态导出的单页应用,所有路由逻辑由客户端index.html处理,但CloudFront默认会直接向S3请求对应路径的实体文件(比如访问/about时,CloudFront会查找S3中是否存在about对象),而这类对象实际不存在,因此返回404。直接访问S3静态网站托管时正常,是因为S3静态网站端点会自动将非文件请求转发到index.html,但你的CloudFront配置使用的是S3 REST API端点,且未配置正确的错误重定向规则。
以下是具体修改方案:
1. 调整CloudFront Origin为S3静态网站托管端点
首先确保你的S3 Bucket已开启静态网站托管,并配置索引文档为index.html(错误文档也指向index.html):
resource "aws_s3_bucket_website_configuration" "production" { bucket = aws_s3_bucket.production_webiste_s3.id index_document { suffix = "index.html" } error_document { key = "index.html" } }
然后修改CloudFront的Origin配置,使用S3静态网站托管的端点(而非Bucket的REST API域名):
origin { domain_name = aws_s3_bucket_website_configuration.production.website_endpoint origin_id = aws_s3_bucket.production_webiste_s3.id custom_origin_config { http_port = 80 https_port = 443 origin_protocol_policy = "http-only" # S3静态网站托管仅支持HTTP协议 } }
2. 修改CloudFront自定义错误响应规则
将404、403错误请求重定向到/index.html,并返回200状态码,让Next.js客户端路由处理这些路径:
custom_error_response { error_code = 404 response_code = 200 response_page_path = "/index.html" error_caching_min_ttl = 0 # 禁用错误响应缓存,确保路由实时生效 } custom_error_response { error_code = 403 response_code = 200 response_page_path = "/index.html" error_caching_min_ttl = 0 }
3. 完整修改后的CloudFront配置
resource "aws_cloudfront_distribution" "s3_distribution_production" { origin { domain_name = aws_s3_bucket_website_configuration.production.website_endpoint origin_id = aws_s3_bucket.production_webiste_s3.id custom_origin_config { http_port = 80 https_port = 443 origin_protocol_policy = "http-only" } } enabled = true is_ipv6_enabled = true default_root_object = "index.html" aliases = ["mycoolwebsite.io"] default_cache_behavior { allowed_methods = ["GET", "HEAD"] cached_methods = ["GET", "HEAD"] target_origin_id = aws_s3_bucket.production_webiste_s3.id forwarded_values { query_string = false cookies { forward = "none" } } viewer_protocol_policy = "redirect-to-https" min_ttl = 0 default_ttl = 120 max_ttl = 300 } viewer_certificate { acm_certificate_arn = aws_acm_certificate.multi_domain_cert.arn ssl_support_method = "sni-only" } restrictions { geo_restriction { restriction_type = "none" } } custom_error_response { error_code = 404 response_code = 200 response_page_path = "/index.html" error_caching_min_ttl = 0 } custom_error_response { error_code = 403 response_code = 200 response_page_path = "/index.html" error_caching_min_ttl = 0 } }
注意事项
- 部署修改后,需等待CloudFront分发更新完成(通常10-15分钟)
- S3静态网站托管端点为公开HTTP服务,无需配置Origin Access Identity
内容的提问来源于stack exchange,提问作者Sasha Shpota
相关产品推荐
相关产品推荐

