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

如何通过Lambda Edge在CloudFront源请求中设置S3存储桶路径

解决Lambda@Edge修改S3静态网站源路径的问题

问题分析

你的核心需求是将原始请求中的网站URL(对应S3桶根目录下的文件夹名称)作为路径前缀,转发到S3静态网站托管源。之前的尝试失败是因为对Lambda@Edge修改源请求的逻辑理解有误,尤其是针对S3静态网站源(而非S3 REST API源)的格式要求。

正确解决方案

Lambda@Edge在**源请求(Origin Request)**阶段修改请求时,需要正确调整origin.custom.path和request.uri两个字段,确保符合S3静态网站托管的路径规则:

场景1:从请求URI中提取网站URL

如果用户通过CloudFront路径访问(例如https://your-cf-domain.com/example.com/page.html),可以从URI中拆分出网站URL作为S3路径前缀:

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const origin = request.origin.custom;
    
    // 拆分URI,提取第一个部分作为网站URL(即S3文件夹名称)
    const uriSegments = request.uri.split('/').filter(seg => seg);
    if (!uriSegments.length) {
        // 处理根路径请求,可根据需求调整默认行为
        callback(null, request);
        return;
    }
    
    const websiteFolder = uriSegments[0];
    // 设置源路径:必须以"/"开头
    origin.path = `/${websiteFolder}`;
    
    // 调整URI为剩余的资源路径,空路径默认指向index.html
    uriSegments.shift();
    request.uri = uriSegments.length ? `/${uriSegments.join('/')}` : '/index.html';
    
    callback(null, request);
};

场景2:从Host头提取网站URL

如果用户通过自定义域名(网站URL)直接访问(例如https://example.com/page.html),则从Host头中获取网站URL作为S3路径前缀:

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const origin = request.origin.custom;
    
    // 从Host头获取网站URL
    const websiteFolder = request.headers.host[0].value;
    // 设置源路径:必须以"/"开头
    origin.path = `/${websiteFolder}`;
    
    // 根路径请求默认指向index.html
    if (request.uri === '/') {
        request.uri = '/index.html';
    }
    
    callback(null, request);
};

为什么之前的尝试失败

  • 修改querystring或uri:直接修改这两个字段会导致CloudFront向S3发送错误的请求格式(例如把网站URL当成查询参数或错误的资源路径),S3无法识别对应的文件夹,因此返回"The specified bucket does not exist"。
  • 修改origin.custom.path格式错误:S3静态网站源要求path必须以/开头,且不能包含非法字符(如冒号、多斜杠等),格式不符合要求时会返回"Invalid path"。
  • 追加到domainName:域名字段仅允许合法的域名格式,不能包含路径部分,因此拼接路径后的域名会被判定为无效,返回"Invalid domainName"。

注意事项

  1. 确保S3桶的文件夹名称与网站URL完全一致(区分大小写)。
  2. Lambda@Edge函数必须部署到us-east-1区域,并关联到CloudFront分发的源请求触发事件。
  3. 验证S3桶权限,确保CloudFront可以访问目标文件夹下的资源。
  4. 测试时可通过CloudFront日志查看修改后的请求路径是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:30:55