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

如何在CloudFront的Viewer Response中添加精准的CloudFront-Viewer-Country头?

无需外部服务,在CloudFront Viewer Response阶段添加精准CloudFront-Viewer-Country头

核心思路

CloudFront在Viewer Request阶段会基于访问者IP实时生成CloudFront-Viewer-Country头,这个头是每个请求独立计算的,不受缓存内容影响。我们可以在Viewer Response阶段直接读取这个请求头,将其添加到响应中,既保证精准性,又不会破坏缓存策略。

实现步骤

1. 确认Viewer Request头的可用性

CloudFront默认会在Viewer Request事件中注入CloudFront-Viewer-Country头,无需额外配置源请求策略(源请求策略是给源站传头用的,这里我们不需要给源站传,只需要在边缘读取)。

2. 编写Viewer Response Lambda@Edge函数

以下是Node.js示例代码,直接从请求中提取头并添加到响应:

exports.handler = (event, context, callback) => {
    const response = event.Records[0].cf.response;
    const request = event.Records[0].cf.request;
    
    // CloudFront会将请求头转为小写,所以用小写键读取
    const countryHeader = request.headers['cloudfront-viewer-country'];
    
    if (countryHeader) {
        // 将头添加到响应,保持和原头一致的格式
        response.headers['cloudfront-viewer-country'] = countryHeader;
    }
    
    callback(null, response);
};

3. 关键配置确保缓存不失效

  • 该函数仅修改响应头,不会更改任何影响缓存键的请求属性(如URL、请求头、查询参数等),因此CloudFront仍会正常使用原缓存键命中缓存,不会导致缓存失效。
  • 不要在函数中修改Cache-Control等缓存相关响应头,除非你有特殊业务需求,否则保持源站返回的缓存策略不变。

注意事项

  • 头名大小写:CloudFront处理请求头时会统一转为小写,所以读取时要用cloudfront-viewer-country;响应头可以用小写或标准的CloudFront-Viewer-Country,浏览器会自动兼容。
  • 未覆盖区域:CloudFront对极少数IP无法解析国家时,会返回XX,这是CloudFront的原生限制,无法通过Lambda解决,若需要处理这种情况,可以在函数中添加默认值逻辑。
  • Lambda部署要求:Lambda@Edge函数必须部署在us-east-1区域,并且需要关联到CloudFront分发的Viewer Response事件。
  • 权限配置:确保Lambda函数拥有必要的调用权限,并且信任关系允许CloudFront触发该函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 16:21:02