AWS CloudFront-转发用户代理,但不对其进行缓存

Nev*_*eue 4 user-agent http amazon-cloudfront

我希望我的原籍能够看到User-Agent标题.eg:Gecko/20100101 Firefox/62.0not Amazon CloudFront

在“行为”选项卡中,我可以将User-Agent标头列入白名单,这样便可以正确地将标头传递到源,但是现在CloudFront缓存per的内容User-Agent,这意味着从不同浏览器访问CloudFront端点的用户将强制CloudFront转到源。

有什么方法可以配置CloudFront以将一些标头传递到源,但不一定要针对它们进行缓存?

编辑:我有与Accept-Language标题类似的问题。我想将其传递给原点,但是我不想针对它进行缓存。我正在缓存的资产与语言无关,但是不可缓存的内容取决于Accept-Language标题。

dom*_*s86 16

亚马逊似乎在 2020 年 7 月左右推出了新功能“Origin Request 策略”。您应该能够使用它(不会陷入 Lambda@Edge 的困境):https://aws.amazon.com/blogs/networking-and-content-delivery/amazon-cloudfront-announces-cache-and-origin-request -政策/

\n

总而言之:

\n
\n

随着时间的推移,我们\xe2\x80\x99已经看到了许多新功能对客户有用的案例。例如:

\n
    \n
  • 将用户代理等信息转发到源进行分析/日志记录,但不根据设备类型提供不同的内容变体(现在您可以转发用户代理标头并将其从缓存键中排除)
  • \n
\n
\n

^ 这是您的用例:)

\n

  • 有趣的是,我刚刚阅读了 AWS 上的文档,它们告诉我这是不可能的,但是转到 Cloudfront 控制台,它显然是使用(相对)新的源请求策略。我想说这个答案现在已经成为正确的答案...... (2认同)

ill*_*nan 9

您可以使用分配给CloudFront分布的Lambda @ Edge函数(https://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html)。您将需要两个功能:

  1. Viewer-Request事件处理程序,将读取User-Agent标头并将其复制到例如X-My-User-Agent。在来自客户端的请求到达您的Cloudfront分发之前,将调用Viewer-Request处理程序。
  2. Origin-Request事件处理程序,将读取X-My-User-Agent并替换User-Agent。当Cloudfront在其缓存中未找到请求的页面并将其发送到源时,将调用Origin-Request处理程序。

请注意,您不应添加User-Agent到Cloudfront白名单中:

您可以将CloudFront配置为根据Date和User-Agent标头中的值缓存对象,但我们不建议这样做。这些标头具有很多可能的值,基于它们的值进行缓存会导致CloudFront向您的来源转发更多的请求。

参考:https : //docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#request-custom-headers-behavior

Viewer-Request处理程序的示例(Lambda @ Edge只能用NodeJS编写,请参考:https : //docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html#lambda-requirements-lambda -function-configuration):

'use strict';

exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const headers = request.headers;
  const customUserAgentHeaderName = 'X-My-User-Agent';
  const userAgent = headers['user-agent'][0].value;


  headers[customUserAgentHeaderName.toLowerCase()] = [
    {
      key: customUserAgentHeaderName,
      value: userAgent
    }
  ];


  callback(null, request);
};
Run Code Online (Sandbox Code Playgroud)

原始请求处理程序的示例:

'use strict';

exports.handler = (event, context, callback) => {
  const request = event.Records[0].cf.request;
  const headers = request.headers;
  const customUserAgentHeaderName = 'X-My-User-Agent';
  const realUserAgent = headers[customUserAgentHeaderName.toLowerCase()][0].value;

  headers['user-agent'] = [
    {
      key: 'User-Agent',
      value: realUserAgent
    }
  ];


  callback(null, request);
};
Run Code Online (Sandbox Code Playgroud)