我在Amazon S3上使用django-storage。我间歇地看到以下错误:
name = self._normalize_name(self._clean_name(name))\n\n File \"/app/.heroku/venv/lib/python2.7/site-packages/storages/backends/s3boto.py\", line 237, in _normalize_name\n name)\n\nSuspiciousOperation: Attempted access to 'https:/plantvillage.s3.amazonaws.com/avatar/hans9_avatar.jpg'
请注意/
之后的单https:
。
有谁知道为什么会出现这种情况?它不会一直发生。我可以在其他情况下成功地做到这一点。
答案 0 :(得分:3)
_normalize_name 在使用URL的Django内容上做了很多花哨和大多数不必要的事情。在我的情况下,我只是覆盖 S3BotoStorage ,如下所示:
class S3CustomStorage(S3BotoStorage):
def _normalize_name(self, name):
"""
Get rid of this crap: http://stackoverflow.com/questions/12535123/django-storages-and-amazon-s3-suspiciousoperation
"""
return name
然后在存储属性中使用它:
ImageField(storage=S3CustomStorage())
它适用于具有此基本配置的django simple ImageField:
AWS_ACCESS_KEY_ID = 'TTTT'
AWS_SECRET_ACCESS_KEY = 'XXXX'
AWS_STORAGE_BUCKET_NAME = 'ZZZZ'
答案 1 :(得分:2)
使用default_storage方法时,请确保使用file.name:
正确:
default_storage.delete(file.name)
错:
default_storage.delete(file.url)
错:
default_storage.delete(file)
上面的所有三个示例都使用本地文件,但是当使用s3时,除非使用file.name,否则将遇到此错误。
答案 2 :(得分:1)
我还没有让S3存储工作在我自己的项目上,但我确实遇到了这个错误,并且可能会指出你正确的方向。
如果你看一下S3BotoStorage._clean_name(),它只是:return os.path.normpath(name).replace('\\', '/')
。
os.path.normpath()将URL中的 // 转换为 \\ ,然后.replace()将其转换为 \ 。然后,S3BotoStorage._normalize_name()检查以确保这个损坏的URL是它所代表的位置的一部分,当然它不是。这就是提出SuspiciousOperation错误的地方。
所以'name'看起来像是本地路径,而不是整个AWS URL。在我的情况下,立即原因是settings.py中的FILEBROWSER_DIRECTORY = MEDIA_URL + "uploads/"
,我曾试图修复有关丢失上传文件夹的其他错误。
答案 3 :(得分:0)
设置
MEDIA_ROOT=''
为我解决了这个问题。
答案 4 :(得分:-1)
我修复此问题,添加了SuspiciousOperation,除了:
class S3CustomStorage(S3BotoStorage):
def _normalize_name(self, name):
try:
return safe_join(self.location, name)
except (SuspiciousOperation, ValueError):
return ""