Django中CSS相对路径在Amazon S3环境下失效问题求助
Hey there, let's dig into why your static files (especially fonts) aren't loading from S3 even though they're publicly accessible and you can open them directly via URL. I've fixed this exact issue a few times, so let's go through the most likely fixes step by step.
Your current settings.py snippet is missing critical settings that tell Django to actually use S3 for serving static files. Add these lines:
# Install django-storages first, then add this to use S3 for static files STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage' # Define the full static file URL using your S3 domain STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/' # Optional: If you're using media files too, add these MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/' DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
Don't forget to install the required packages and add storages to your apps:
pip install django-storages boto3
INSTALLED_APPS = [ # ... your existing apps 'storages', # Add this line ]
AWS_S3_CUSTOM_DOMAIN definition Your current line cuts off halfway—you need to fully define the domain with your bucket name:
AWS_S3_CUSTOM_DOMAIN = f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com"
If you're using a CDN like CloudFront, replace this with your CDN domain instead, but for plain S3, the above is required.
Just putting files in your local static folder isn't enough—you need to upload them to S3 using Django's collectstatic command:
python manage.py collectstatic
Run this and confirm it completes without errors. This command pulls all files from your STATICFILES_DIRS and uploads them to your S3 bucket.
static tag If you're hardcoding URLs in templates, Django won't use the S3 URL you configured. Always use the static template tag:
# First, load the tag at the top of your template {% load static %} # Correct way to reference files <img src="{% static 'images/hero.jpg' %}" alt="Hero Image"> <link rel="stylesheet" href="{% static 'css/main.css' %}"> @font-face { font-family: 'MyFont'; src: url("{% static 'fonts/myfont.woff2' %}") format('woff2'); }
Avoid hardcoding paths like /static/images/hero.jpg—this will point to your local server instead of S3.
Font files often fail to load due to CORS restrictions, even if they're public. Head to your S3 bucket in the AWS console:
- Go to the Permissions tab
- Find Cross-origin resource sharing (CORS)
- Paste this configuration (adjust
AllowedOriginto your actual domain if you don't want to allow all):
<CORSConfiguration> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration>
Save the changes—this should resolve font loading blocked by CORS policies.
Open your browser's dev tools (F12), go to the Network tab, and refresh the page. Look at the failed requests:
- 404 Error: The file doesn't exist at the S3 path you're requesting. Double-check
collectstaticran successfully and your template paths are correct. - 403 Error: Permission issue—confirm your bucket policy allows public read access, and your IAM user (from
AWS_ACCESS_KEY_ID) has permissions to access the files. - CORS Error: You need to adjust the CORS config as mentioned in step 5.
内容的提问来源于stack exchange,提问作者Alastair W

