【问题标题】:Add content-type for specific file types in Amazon CloudFront?在 Amazon CloudFront 中为特定文件类型添加内容类型?
【发布时间】:2019-03-17 05:08:05
【问题描述】:

我有一个使用 CloudFront 提供服务的 S3 存储桶。我想从中提供一些 JSON 文件。

开箱即用,CF 响应根本不包含此文件类型的任何 Content-Type 标头。该文件只是由浏览器作为任何常规文件下载。但是,我希望它有一个适当的 mime 类型标题:Content-Type: application/json

我知道,我可以在 S3 中手动为任何单个文件设置自定义标头,但是,是否可以为特定文件扩展名指定一些规则以将特定 HTTP 标头添加到 Amazon CloudFront 中的响应中?

【问题讨论】:

    标签: amazon-web-services amazon-s3 amazon-cloudfront


    【解决方案1】:

    如果您无法控制如何将对象上传到您的 S3 存储桶,您可以使用 Lambda@Edge 函数来覆盖响应标头,如下所示:

    (这种方法的缺点是它会增加延迟并产生额外的成本)

    1. 创建将在下一步中附加到您的 lambda 函数角色的 IAM 策略:

      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Sid": "StatementForCloudWatchLogs",
                  "Effect": "Allow",
                  "Action": [
                      "logs:CreateLogGroup",
                      "logs:CreateLogStream",
                      "logs:PutLogEvents"
                  ],
                  "Resource": "*"
              },
              {
                  "Sid": "StatementForLambdaFunction",
                  "Effect": "Allow",
                  "Action": [
                      "lambda:EnableReplication",
                      "lambda:GetFunction"
                  ],
                  "Resource": [
                      "arn:aws:lambda:us-east-1:{YOUR_ACCOUNT_ID}:function:{FUNCTION_NAME}:{FUNCTION_VERSION}"
                  ]
              },
              {
                  "Sid": "StatementForIAMServiceLinkedRoles",
                  "Effect": "Allow",
                  "Action": [
                      "iam:CreateServiceLinkedRole"
                  ],
                  "Resource": "arn:aws:iam::{YOUR_ACCOUNT_ID}:role/*"
              },
              {
                  "Sid": "StatementForCloudFrontDistributions",
                  "Effect": "Allow",
                  "Action": [
                      "cloudfront:CreateDistribution",
                      "cloudfront:UpdateDistribution"
                  ],
                  "Resource": "*"
              }
          ]
      }
      
    2. 为 lambda 创建一个新的 AWS 服务 IAM 角色,并将您在步骤 1 中创建的策略附加到该角色。在信任关系下,确保两者都有; lambda.amazonaws.comedgelambda.amazonaws.com 作为可信实体。

    3. 创建您的 lambda 函数,然后发布一个新版本(在 Actions 下)。您必须使用 nodejs6.10 运行时属性创建函数:

      'use strict';
      
      exports.handler = (event, context, callback) => {
         const response = event.Records[0].cf.response;
      
         if (response.status === '200') {
             response.headers['content-type'] = [{
                 'value': 'application/json', // <-- Your desired content type.
                 'key': 'Content-Type'
             }];
         }
      
         callback(null, response);
      };
      
    4. 为您的 CloudFront 分配中的 json 文件创建一个新行为(例如,path/to/your/json/*.json)并确保它位于Default (*) 行为之上。

    5. 在新创建的行为的 Lambda 函数关联 下,选择 Origin Response 事件类型并输入在步骤 3 中创建的 lambda 函数的 ARN。对于例如:arn:aws:lambda:us-east-1:{YOUR_ACCOUNT_ID}:function:{FUNCTION_NAME}:{FUNCTION_VERSION}。 (注意:您的 lambda 函数必须在美国东部(弗吉尼亚北部)区域创建,并且函数 ARN 必须具有编号版本,而不是 $LATEST 或别名。
    6. 为您的 path/to/your/json/* 文件创建 CloudFront 失效。

    请务必阅读Requirements and Restrictions on Lambda Functions

    另请参阅Lambda Event Structure 了解更多信息。

    【讨论】:

      【解决方案2】:

      更新:CloudFront 本身不提供用于操作标头的内置机制,但与 CloudFront 结合使用的 Lambda@Edge 提供了一种机制来创建可以检查和修改原始响应标头的挂钩。它实际上不能检查响应正文,但可以注入静态或启发式衍生的标头。如果内容来自已知/受信任的来源并且内容类型已知,这可能是一种可行的解决方法,但可能不应该用于用户提交的内容,因为不正确的内容类型可能会导致浏览器误解有效负载,并且可能是一个潜在的利用向量。在上传对象时正确设置对象的内容类型可能仍然是更好的解决方案。

      这里的原始答案早于 Lambda@Edge,并且指的是 CloudFront 本身的本机功能。


      CloudFront 使用源服务器提供的响应标头,无论是 S3 还是自定义源。 CloudFront 不提供重写或添加它们的机制。

      解决方案是在最初将对象上传到 S3 时在对象上设置Content-Type

      如果您将文件上传到 S3 并设置了 Content-Type,则在下载对象时将返回相同的值(无论是直接从 S3 还是通过 CloudFront)。否则,如果您不想要 S3 在未指定时分配的默认 Content-Type: binary/octet-stream 标头,则必须在上传后修改对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-13
        • 2016-06-09
        • 2018-02-24
        • 2018-07-17
        • 2011-03-19
        • 2020-08-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多