无法在S3中设置文件内容类型

2024-06-28 10:53:42 发布

您现在位置:Python中文网/ 问答频道 /正文

如何通过Python boto模块在启用webhosting的S3帐户中设置文件的内容类型?

我在做:

from boto.s3.connection import S3Connection
from boto.s3.key import Key
from boto.cloudfront import CloudFrontConnection

conn = S3Connection(access_key_id, secret_access_key)
bucket = conn.create_bucket('mybucket')
b = conn.get_bucket(bucket)
b.set_acl('public-read')

fn = 'index.html'
template = '<html>blah</html>'
k = Key(b)
k.key = fn
k.set_contents_from_string(template)
k.set_acl('public-read')
k.set_metadata('Content-Type', 'text/html')

但是,当我从http://mybucket.s3-website-us-east-1.amazonaws.com/index.html访问它时,我的浏览器会提示我下载该文件,而不是仅仅将其作为网页使用。

查看S3管理控制台中的元数据,可以看到Content-Type实际上已经设置为“application/octet stream”。如果我在控制台中手动更改它,我可以正常访问页面,但如果我再次运行脚本,它会将其重置回错误的内容类型。

我做错什么了?


Tags: 文件keyfromimport类型内容s3bucket
3条回答

对于需要一个班轮的人来说

import boto3
s3 = boto3.resource('s3')

s3.Bucket('bucketName').put_object(Key='keyName', Body='content or fileData', ContentType='contentType', ACL='check below')

支持的ACL值:

'private'|'public-read'|'public-read-write'|'authenticated-read'|'aws-exec-read'|'bucket-owner-read'|'bucket-owner-full-control'

put_object支持的参数可以在这里找到,https://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.put_object

set_metadata方法实际上用于在S3对象上设置用户元数据。许多标准的HTTP元数据字段都有一级属性来表示它们,例如content_type。另外,您希望在实际将对象发送到S3之前设置元数据。这样的做法应该管用:

import boto

conn = boto.connect_s3()
bucket = conn.get_bucket('mybucket')  # Assumes bucket already exists
key = bucket.new_key('mykey')
key.content_type = 'text/html'
key.set_contents_from_string(mystring, policy='public-read')

注意,您可以在将对象写入S3时设置屏蔽ACL策略,这样就不必再进行另一个API调用。

我无法获得上面的解决方案来实际持久化我的元数据更改。

也许是因为我使用的是一个文件,它正在使用mimetype重置内容类型?此外,我正在上传m3u8和ts文件,以便HLS编码,这样也可能会干扰。

不管怎样,这是对我有用的。

import boto
conn = boto.connect_s3()
bucket = conn.get_bucket('mybucket')
key_m3u8 = Key(bucket_handle)
key_m3u8.key = s3folder+"/"+s3keyname
key_m3u8.metadata = {"Content-Type":"application/x-mpegURL","Cache-Control":"public,max-age=8"}                             
key_m3u8.set_contents_from_filename("path_to_my_file", policy="public-read")

相关问题 更多 >