我有一个django项目,可以将文件上传到AWS S3存储桶。如果上传的文件和静态文件使用{% static %}
标记在模板中呈现,则会正确显示这些文件和静态文件。但是,当我想使用model_object.image.url
在javascript代码中访问图片时,图片不会显示。我检查了代码,获取了在js代码中呈现的url并将其粘贴到浏览器上,它给了我这个错误:
<Error>
<Code>AccessDenied</Code>
<Message>Query-string authentication requires the Signature, Expires and AWSAccessKeyId parameters</Message>
<RequestId>xxxx</RequestId><HostId>xxx</HostId>
</Error>
可能有用的更多信息:
用户上传图像,然后他可以裁剪图像。我为此使用了Croppie,它是一个使用图像网址的js库,如下所示:
$('.div').croppie({
url: '{{ model_object.image.url }}',
});
一切都在本地运作。这是AWS的一个问题我显然不明白。
在solarissmoke
评论之后,我将此存储桶策略添加到我的存储桶中:
{
"Version": "2012-10-17",
"Id": "Policy1468082822770",
"Statement": [
{
"Sid": "Stmt1468082812651",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::criptolibertad/*"
}
]
}
然而,它仍然无效。我注意到在模板中呈现的不起作用的URL看起来像这样:
https://criptolibertad.s3.amazonaws.com/Django/0_squashmigrations.jpeg?Signature=HFDdOYvrfqz5DG ...
如果我直接从我的存储桶中打开资源,则网址如下所示:
https://s3-us-west-2.amazonaws.com/criptolibertad/Django/0_squash+migrations.jpeg?X-Amz-Date=201607 ...
我也右键单击了该文件夹并选择Make Public
以防万一。
任何建议都会有所帮助。
答案 0 :(得分:1)
首先,上面的链接指向不同的路径,一个是文件Django/0_squash+migrations.jpeg
,另一个是Django/0_squashmigrations.jpeg
。
后者是不适合我的人,它似乎缺少一个+字符(空格?);我根本无法访问该文件(我收到访问错误)。我会认为这只是你的错字。
熟悉your code(如果您希望链接被修改,请告诉我),我已经模拟了图片上传,甚至将您的策略复制到我的存储桶中。
我注意到我的model_objecct.image.url
与你的不同之处在于它包括AWSAccessKeyId,如下所示:
> fs = FeralSpirit.objects.all()[1]
> print(fs.imagen.url)
https://so38134984.s3.amazonaws.com/OrillaLibertaria/Users/pavel/dev/temp/so38134984/rainbow_dash2.png?Signature=****&Expires=*****&AWSAccessKeyId=*******
示例中的链接仅包含签名,因此您看到的错误消息非常合适。
事实上,我们可以在没有任何查询字符串的情况下访问the image above。
如果您尝试删除查询字符串参数,因为这将是一个可公开访问的存储桶,请尝试将AWS_QUERYSTRING_AUTH = False
添加到您的Django设置中。这应该生成没有任何查询字符串参数的url:
> fs = FeralSpirit.objects.all()[1]
> fs.imagen.url
'https://so38134984.s3.amazonaws.com/OrillaLibertaria/Users/pavel/dev/temp/so38134984/rainbow_dash2.png'
当然,这仍然可以公开访问。
答案 1 :(得分:0)
好的,感谢 tutuDajajo 以及他在this问题中的答案,当我缩小问题范围时,我发现了问题和解决方案:
Croppie.js正试图将图片加载到HTML5画布中。 Croppie.js自动将crossorigin="anonymous"
添加到图像中。但是图像缺少正确的CORS标题,因此画布被“污染”了。
我发现更改Croppie.js源并删除crossorigin="anonymous"
部分工作:图像已正确加载到画布中,但无法导出它并获取我需要发送到服务器的base64图像。
真正的解决方案是改变我的存储桶CORS配置,从而:
<AllowedHeader>Authorization</AllowedHeader>
到此:
<AllowedHeader>*</AllowedHeader>
顺便说一句。 AWS文档不清楚AllowedHeader
选项。