Django 通过签名 url 上传到 Amazon S3:错误的内容类型

Django upload to Amazon S3 via signed urls: wrong content type

在我的 Django 应用程序(RESTful API 和 DjangoRestFramwework)中,我必须将图像存储在 Amazon S3 上。由于某些技术限制,我们必须使用已签名的 URLs 由客户端应用程序直接上传。一切正常,但在客户端执行上传后,内容类型始终设置为 binary/octet-stream,而我自然希望它是 image/jpeg。正如 Amazon S3 文档 here 中提到的,必须将 response-content-type header 添加到已签名的 URL 中,以确保响应的 Content-Type通过 S3 将是正确的。这是我签署 URL 的代码(根据 boto 文档编写):

connection = S3Connection(
    aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
    aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY
)    
url = connection.generate_url(
    100,
    'PUT',
    settings.AWS_STORAGE_BUCKET_NAME,
    some_key,
    response_headers={'response-content-type':'image/jpeg'},
)

此代码几乎可以正常工作:它生成一个 URL,然后我成功地将其用于上传。 curl 请求是:

curl -v --request PUT --upload-file ~/file.jpg --header "response-content-type : image/jpeg" "https://mybucket.s3.amazonaws.com/file.jpg?Signature=ytmFHV13qeVg1aU6xyTuysOG4Bs%3D&Expires=1440263232&AWSAccessKeyId=XXXXXXXXXXXXXXXX&response-content-type=image/jpeg"

不幸的是,当我访问文件时,内容类型仍然是错误的(binary/octet-stream)。我做错了什么吗?

今天,经过大量实验,我找到了答案。我的灵感来自... official Amazon S3 documentation :) 这是 URL 签名代码:

url = connection.generate_url(
    100,
    'PUT',
    settings.AWS_STORAGE_BUCKET_NAME,
    some_key,
    headers = {'x-amz-acl' : 'public-read', 'Content-Type': 'image/jpeg'}
)

这里的主要变化是 headers 部分,我将 'Content-Type': 'image/jpeg' 放在那里('x-amz-acl' : 'public-read' 也很有用,因为它使您的文件可以公开阅读)。然后,您必须将 Content-Type header 放置到您的 HTTP 请求中。就我而言,我使用 curl 如下:

curl -v --request PUT --upload-file ~/file.jpg  --header "Content-Type: image/jpeg" your_signed_url

尽情享受吧!