我已经通过使用 Amazon s3 在 Heroku 上设置我的 Django 应用程序来托管静态和媒体文件。我一直在关注本指南 https://www.caktusgroup.com/blog/2014/11/10/Using-Amazon-S3-to-store-your-Django-sites-static-and-media-files/以及似乎有数千种其他资源的东西,collectstatic 已经工作,heroku 正在部署它 - 但显示 400 错误。当我尝试在本地运行它时,我得到了更多信息:
Attempted access to '/css/reset.css' denied.
这是突出显示的行:
<link rel="stylesheet" type="text/css" href="{% static '/css/reset.css' %}">
如果我从我的 s3 管理面板中抓取静态文件,我可以直接从 URL 加载静态文件,所以我认为这不是存储桶策略问题,我弄乱了 https/http 选项,但没有任何乐趣。所以我认为它一定是在代码中以某种方式调用了错误的路径 - 我只是看不到哪里!
非常感谢任何帮助,我认为我已经连续 4 个小时没有眨眼了。
追溯:
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/storages/backends/s3boto.py" in _normalize_name
358. return safe_join(self.location, name)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/storages/backends/s3boto.py" in safe_join
59. raise ValueError('the joined path is located outside of the base path'
During handling of the above exception (the joined path is located outside of the base path component), another exception occurred:
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/devtop/webdev/projects/intro/intro/profiles/views.py" in index
14. return render(request, 'home.html', {'welcome':welcome})
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/shortcuts.py" in render
30. content = loader.render_to_string(template_name, context, request, using=using)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/loader.py" in render_to_string
68. return template.render(context, request)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/backends/django.py" in render
66. return self.template.render(context)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in render
207. return self._render(context)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/loader_tags.py" in render
177. return compiled_parent._render(context)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/templatetags/static.py" in render
105. url = self.url(context)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/templatetags/static.py" in url
102. return self.handle_simple(path)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/django/templatetags/static.py" in handle_simple
117. return staticfiles_storage.url(path)
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/storages/backends/s3boto.py" in url
487. name = self._normalize_name(self._clean_name(name))
File "/home/devtop/webdev/projects/intro/myvenv/lib/python3.5/site-packages/storages/backends/s3boto.py" in _normalize_name
361. name)
Exception Type: SuspiciousOperation at /
Exception Value: Attempted access to '/css/reset.css' denied.
设置.py
AWS_ACCESS_KEY_ID=os.environ.get('AWS_ACCESS_KEY_ID',None)
AWS_SECRET_KEY=os.environ.get('AWS_SECRET_KEY',None)
AWS_SECRET_ACCESS_KEY=os.environ.get('AWS_SECRET_KEY', None)
AWS_STORAGE_BUCKET_NAME = 'intro-story'
AWS_S3_HOST='s3.us-east-2.amazonaws.com'
AWS_S3_CUSTOM_DOMAIN = 's3.us-east-2.amazonaws.com/%s' % AWS_STORAGE_BUCKET_NAME
AWS_S3_SECURE_URLS = False
STATICFILES_LOCATION = 'static'
STATICFILES_STORAGE = 'custom_storages.StaticStorage'
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)
MEDIAFILES_LOCATION = 'media'
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'
try:
from .local_settings import *
except ImportError:
pass
local_settings.py
AWS_ACCESS_KEY_ID = "xxx"
AWS_SECRET_ACCESS_KEY = "yyy"
custom_storages.py
from django.conf import settings
from storages.backends.s3boto import S3BotoStorage
class StaticStorage(S3BotoStorage):
location = settings.STATICFILES_LOCATION
class MediaStorage(S3BotoStorage):
location = settings.MEDIAFILES_LOCATION
编辑:
我设法通过处理 settings.py 中的各种值来使其工作,但仍然不对。
这是与静态和媒体路径相关的所有内容
STATICFILES_LOCATION = 'static'
MEDIAFILES_LOCATION = 'media'
import custom_storages
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATICFILES_LOCATION)
STATICFILES_STORAGE = 'custom_storages.StaticStorage'
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'
这是我要导入的 custom_storage:
from django.conf import settings
from storages.backends.s3boto import S3BotoStorage
class StaticStorage(S3BotoStorage):
location = settings.STATICFILES_LOCATION
class MediaStorage(S3BotoStorage):
location = settings.MEDIAFILES_LOCATION
现在,如果我注释掉
STATICFILES_STORAGE = 'custom_storages.StaticStorage'
它将从 S3 加载静态文件,一切正常,但 collectstatic 失败。如果我取消注释该行,collectstatic 会起作用,但是当我尝试加载站点时会出现错误。错误是:
# Ensure final_path starts with base_path and that the next character after
# the final path is '/' (or nothing, in which case final_path must be
# equal to base_path).
base_path_len = len(base_path)
if (not final_path.startswith(base_path) or
final_path[base_path_len:base_path_len + 1] not in ('', '/')):
raise ValueError('the joined path is located outside of the base path' ...
' component')
return final_path.lstrip('/')
很明显,custom_storage 部分出了点问题,但我不知道是什么:/
最佳答案
排序!正如预期的那样,这是一件令人讨厌的简单事情,但也许这会帮助其他遇到同一堵墙的人。
这个:
<link rel="stylesheet" type="text/css" href="{% static '/css/reset.css' %}">
需要是这样的:
<link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">
IE。 href 中没有前导斜杠。使用本地静态文件存储工作正常,但破坏了 S3 链接。
关于django - '可疑操作: Attempted access to "" denied' while loading static files,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43529912/