Render部署Django项目后访问根URL出现400 Bad Request错误求助
问题概述
将Django 5.1.2项目部署到Render平台后,访问根URL(/)始终返回400 Bad Request错误。已确认settings.py中ALLOWED_HOSTS和CSRF_TRUSTED_ORIGINS包含Render域名challo-backend-1.onrender.com,Channels配置使用本地Redis(127.0.0.1:6379)。服务器启动后日志立即出现该错误,且项目几天前运行正常。
相关日志
==> Your service is live 🎉 127.0.0.1 - - [05/Nov/2024:16:41:12 +0000] "GET / HTTP/1.1" 400 143 "-" "Go-http-client/2.0" [2024-11-05 16:42:10 +0000] [95] [INFO] Handling signal: term [2024-11-05 16:42:10 +0000] [98] [INFO] Worker exiting (pid: 98) [2024-11-05 16:42:11 +0000] [95] [INFO] Shutting down: Master
当前settings.py关键配置
""" Django settings for challo project. Generated by 'django-admin startproject' using Django 5.1.2. """ import dj_database_url from pathlib import Path from datetime import timedelta import os from django.core.exceptions import ImproperlyConfigured BASE_DIR = Path(__file__).resolve().parent.parent def get_secret_key(): try: return os.environ['SECRET_KEY'] except KeyError: raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.") SECRET_KEY = get_secret_key() # Allowed Hosts and CSRF Trusted Origins ALLOWED_HOSTS = ['challo-backend-1.onrender.com', '127.0.0.1', 'localhost'] CSRF_TRUSTED_ORIGINS = ['https://challo-backend-1.onrender.com'] # Channel Layers CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [('127.0.0.1', 6379)], }, }, } INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'phonenumber_field', 'rest_framework', 'rest_framework_simplejwt', 'users', 'rides', 'channels', 'chat', 'django_htmx', 'corsheaders' ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] CORS_ALLOW_ALL_ORIGINS = True ROOT_URLCONF = 'challo.urls' WSGI_APPLICATION = 'challo.wsgi.application' ASGI_APPLICATION = "challo.asgi.application" # Database DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } def get_dbKey(): try: return os.environ['DATABASE_URL'] except KeyError: raise ImproperlyConfigured("The DATABASE_URL setting must not be empty.") DATABASE_URL = get_dbKey() DATABASES['default'] = dj_database_url.parse(DATABASE_URL) AUTH_USER_MODEL = 'users.CustomUser' REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ) } SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(days=1), 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), 'ROTATE_REFRESH_TOKENS': True, 'BLACKLIST_AFTER_ROTATION': True, 'UPDATE_LAST_LOGIN': True, } STATIC_URL = 'static/' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
排查与解决方案
1. 修复Redis Channel配置问题
Render平台上无法使用本地Redis(127.0.0.1:6379),需使用Render提供的Redis服务并通过环境变量获取连接信息。修改CHANNEL_LAYERS配置:
CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [os.environ.get('REDIS_URL')], }, }, }
确保已在Render控制台添加Redis服务,并将其连接字符串作为REDIS_URL环境变量注入到Web服务中。
2. 动态配置ALLOWED_HOSTS
Render可能使用内部临时域名进行健康检查,建议通过环境变量动态设置ALLOWED_HOSTS避免遗漏合法域名:
ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS", "challo-backend-1.onrender.com,127.0.0.1,localhost").split(",")
同时在Render环境变量中添加ALLOWED_HOSTS,值为你的域名+127.0.0.1+localhost,用逗号分隔。
3. 切换为ASGI启动命令
项目使用Channels,必须用ASGI服务器(如Daphne)启动,而非WSGI服务器(如Gunicorn)。修改Render启动命令为:
daphne challo.asgi:application --port $PORT --bind 0.0.0.0
4. 验证健康检查与HTTPS配置
日志中的请求来自Render的健康检查(Go-http-client/2.0),确保健康检查目标URL使用你的Render域名而非127.0.0.1。同时配置HTTPS重定向仅在生产环境生效:
SECURE_SSL_REDIRECT = os.environ.get('ENVIRONMENT') == 'production'
添加ENVIRONMENT环境变量为production,确保Render上的请求正确重定向到HTTPS。
内容的提问来源于stack exchange,提问作者Tashinga Bwanali

