无法访问保存在 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.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,它是一个使用图像的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 配置,如下:
<AllowedHeader>Authorization</AllowedHeader>
到这里:
<AllowedHeader>*</AllowedHeader>
顺便说一句。 AWS 文档不清楚 AllowedHeader
选项。
【讨论】:
以上是关于无法访问保存在 Javascript 代码中的存储桶中的图像的主要内容,如果未能解决你的问题,请参考以下文章
我无法访问 index.jsp 中的嵌套 JavaScript 函数
我似乎无法显示我保存在 asp.net 的 ms 访问数据库中的图像