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

CloudFront针对S3子目录中SPA深层路由的动态重定向配置问题求助

Fixing Deep Route 404s for Multi-SPA S3/CloudFront Setup

Let's break down why your current Lambda@Edge isn't working, then fix it with the right approach tailored to your multi-subdirectory SPA setup.

What's Wrong With Your Current Code?

Your Lambda targets the Origin Response event, and here's the critical misstep:

  • You’re setting the response status to 200 but leaving the body empty, which directly causes the blank page you’re seeing.
  • Adding a Location header alongside a 200 status won’t trigger a browser redirect—browsers only act on Location with 3xx status codes. Even if you switched to a 302 redirect, this would rewrite the URL in the address bar, breaking your SPA’s client-side routing entirely.

The core issue is you’re trying to fix the 404 after S3 has already returned it, instead of preventing the 404 in the first place by rewriting the request before it reaches S3.

Correct Solution: Origin Request Lambda@Edge

We’ll use an Origin Request Lambda to rewrite the request URI before it’s sent to S3. This tells CloudFront to fetch the correct index.html from the corresponding subdirectory, while keeping the original URL in the user’s browser (perfect for preserving SPA routing behavior).

Here’s the working code:

exports.handler = (event, context, callback) => {
    'use strict';
    const request = event.Records[0].cf.request;
    const uri = request.uri;

    // Skip if we're already accessing a file (has a file extension) or index.html directly
    if (uri.includes('.') || uri.endsWith('/index.html')) {
        callback(null, request);
        return;
    }

    // Extract the first subdirectory (e.g., "experiment1" from "/experiment1/about")
    const pathSegments = uri.split('/').filter(segment => segment !== '');
    if (pathSegments.length === 0) {
        callback(null, request);
        return;
    }
    const firstSegment = pathSegments[0];

    // Rewrite the URI to point to the subdirectory's index.html
    request.uri = `/${firstSegment}/index.html`;

    callback(null, request);
};

Key Setup Steps & Details

  1. Lambda Deployment:
    • Deploy this Lambda in the us-east-1 (N. Virginia) region (required for all Lambda@Edge functions).
    • When publishing, select "Deploy to Lambda@Edge" and associate it with your CloudFront distribution.
  2. CloudFront Trigger Configuration:
    • Choose the Origin Request event type for your CloudFront behavior (ensure the behavior covers all your /experiment* paths).
  3. Why This Works:
    • For any deep route like /experiment1/about, the Lambda rewrites the request to /experiment1/index.html before it hits S3.
    • S3 returns the correct SPA entry point, and your SPA’s client-side router takes over to render the /about page without altering the user’s URL.
  4. Testing Tips:
    • Clear your browser cache or use incognito mode to avoid cached 404 responses from prior attempts.
    • Verify the Lambda is executing by checking CloudFront access logs or Lambda@Edge monitoring metrics.

Bonus Edge Case Handling

  • If you have root-level paths (not under /experiment*), you can add extra logic to rewrite requests to a root index.html if needed.
  • The code skips requests for static assets (like .js, .css, .png) so your app’s resources still load correctly without interference.

内容的提问来源于stack exchange,提问作者airconductor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 20:57:41