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

Posted

技术标签:

【中文标题】无法访问保存在 Javascript 代码中的存储桶中的图像【英文标题】:Can't access image saved in bucket in Javascript code 【发布时间】:2016-11-11 17:43:47 【问题描述】:

我有一个将文件上传到 AWS S3 存储桶的 django 项目。如果上传的文件和静态文件在模板中使用 % static % 标记呈现,则它们会正确显示。但是,当我想使用 model_object.image.urljavascript 代码中访问图像时,图像不会显示。我检查了代码,获取了在 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,它是一个使用图像的url的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...

如果我直接从我的存储桶中打开资源,则 url 如下所示:

https://s3-us-west-2.amazonaws.com/criptolibertad/Django/0_squash+migrations.jpeg?X-Amz-Date=201607...

我还右键单击该文件夹并选择了Make Public以防万一。

任何建议都会有所帮助。

【问题讨论】:

看起来您的 S3 存储桶/对象不是公开的,它们需要在没有身份验证的情况下访问它们。有关一些想法,请参阅this question。 @solarissmoke 感谢您的评论,我现在添加了一项政策。但是还是不行。 【参考方案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'

当然,这仍然可以公开访问。

【讨论】:

感谢您的回答,我刚刚编辑并实现了这个问题。 你的问题现在和S3关系不大,建议你编辑回问题,再问一个新的 开始之前,请检查 chrome 开发者工具日志中是否有任何错误 @tutuDajaju 我在问题中添加了错误...我没有想法了。 好的@tutuDajuju 我同意。然而,考虑到我已经尝试了所有想到的东西,甚至问了this 到现在都没有答案的新问题,我决定以一种奇怪的方式解决这个问题。谢谢大家的关注。 GL HF。【参考方案2】:

好的,感谢tutuDajajo和他在this问题中的回答,当我缩小问题范围时,我找到了问题和解决方案:

Croppie.js 试图将图像加载到 html5 画布中。 Croppie.js 自动将crossorigin="anonymous" 添加到图像中。但是图像缺少正确的 CORS 标头,因此画布被“污染”。

我发现更改 Croppie.js 源并删除 crossorigin="anonymous" 部分起作用:图像已正确加载到画布中,但无法导出它并获取我需要发送到服务器的 base64 图像。

真正的解决方案是更改我的存储桶 CORS 配置,如下:

&lt;AllowedHeader&gt;Authorization&lt;/AllowedHeader&gt;

到这里:

&lt;AllowedHeader&gt;*&lt;/AllowedHeader&gt;

顺便说一句。 AWS 文档不清楚 AllowedHeader 选项。

【讨论】:

以上是关于无法访问保存在 Javascript 代码中的存储桶中的图像的主要内容,如果未能解决你的问题,请参考以下文章

无法保存访问数据库的更改

无法保存到 Dojo 中的存储

我无法访问 index.jsp 中的嵌套 JavaScript 函数

我似乎无法显示我保存在 asp.net 的 ms 访问数据库中的图像

如何通过 HTML 中的 JavaScript 在 Django 中保存模型实例

在已保存时间和当前时间之间计算本地存储 javascript