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

配置CloudFront+S3源:实现JSON文件浏览器内预览而非下载

问题:CloudFront访问JSON文件自动下载,需改为浏览器内显示

我通过Terraform(用Terragrunt封装)创建了CloudFront分发、CloudFront OAI及S3存储桶,桶内存储有一个简单的JSON文件,且已正确配置OAI策略。但通过分发URL在浏览器访问该JSON文件时,文件会自动下载到本地而非在浏览器中显示,不符合预期。

相关配置

CloudFront分发配置

resource "aws_cloudfront_distribution" "s3_distribution" {
  origin {
    domain_name = var.bucket_regional_domain_name
    origin_id = var.origin_id
    s3_origin_config {
      origin_access_identity = aws_cloudfront_origin_access_identity.default.cloudfront_access_identity_path
    }
  }
  enabled             = true
  default_root_object = "final_catalog.json"

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = var.origin_id

    forwarded_values {
      query_string = false
      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "allow-all"
    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
  }
  viewer_certificate {
    cloudfront_default_certificate = true
  }
  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  tags = {
    Name = "CloudFront_Distribution"
    Owner = "Gilad_Tayeb"
    Terraform = "True"
  }
}

resource "aws_cloudfront_origin_access_identity" "default" {
  comment = "Origin access identity for the distribution"
}

S3存储桶配置

resource "aws_s3_bucket" "my_bucket" {
  bucket = var.bucket_name
}

resource "aws_s3_bucket_versioning" "my_bucket_versioning" {
  bucket = aws_s3_bucket.my_bucket.id
  versioning_configuration {
    status = "Enabled"
  }
}

data "aws_iam_policy_document" "allow_oai_access" {
   statement {
     actions   = ["s3:GetObject"]
     resources = ["${aws_s3_bucket.my_bucket.arn}/*"]

     principals {
       type        = "AWS"
       identifiers = [var.cloudfront_oai_arn]
     }
   }
 }

resource "aws_s3_bucket_policy" "allow_cloudfront_oai" {
  bucket = aws_s3_bucket.my_bucket.id
  policy = data.aws_iam_policy_document.allow_oai_access.json
}

Python上传脚本(boto3)

def upload_filtered_products_to_s3(self):
    with open('final_catalog.json', 'r') as json_file:
        read_data = json.load(json_file)
    bucket_upload = self.client.put_object(
        Bucket=self.bucket_name,
        Body=json.dumps(read_data),
        Key="final_catalog.json",
        ContentType="text/json"
    )

解决方案

问题核心是浏览器根据返回的Content-Type和Content-Disposition响应头决定内容展示方式。当前配置中,要么是MIME类型不标准,要么缺少强制内联的头信息,导致浏览器触发下载行为。可通过以下方式调整:

1. 修正S3上传的元数据

你当前使用的text/json并非标准JSON MIME类型,浏览器对application/json支持更完善。同时添加ContentDisposition头强制浏览器内联显示:

bucket_upload = self.client.put_object(
    Bucket=self.bucket_name,
    Body=json.dumps(read_data),
    Key="final_catalog.json",
    ContentType="application/json",  # 改为标准MIME类型
    ContentDisposition="inline"      # 明确指定内联显示
)

2. 在CloudFront中配置自定义响应头(可选)

如果无法修改上传脚本,可在CloudFront缓存行为中添加自定义响应头,覆盖S3返回的元数据:
修改CloudFront分发的default_cache_behavior部分,新增custom_response_headers配置:

default_cache_behavior {
  # 保留原有配置...

  custom_response_headers {
    quantity = 2
    items {
      header = "Content-Type"
      value = "application/json"
      override = true
    }
    items {
      header = "Content-Disposition"
      value = "inline"
      override = true
    }
  }
}

3. 刷新CloudFront缓存

由于你设置的TTL为0,理论上不会缓存旧内容,但建议手动刷新CloudFront缓存(通过控制台"Invalidations"提交/*路径),确保新的响应头立即生效。

4. 验证S3对象元数据

修改后到S3控制台查看final_catalog.json的元数据,确认Content-Type为application/json、Content-Disposition为inline,确保配置已生效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 04:50:20