无法在Javascript代码中访问存储在存储桶中的图像

时间:2016-07-09 05:46:18

标签: javascript django amazon-s3

我有一个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以防万一。

任何建议都会有所帮助。

2 个答案:

答案 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选项。