配置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
相关产品推荐
相关产品推荐

