部署至Vercel后Swagger无法正常显示,请求排查原因
Django部署Vercel后Swagger /docs端点报错问题
问题现象
将Django项目部署到Vercel后,访问/docs端点(Swagger文档页面)时出现错误:页面样式错乱,Swagger依赖的CSS、JavaScript等静态资源加载失败(返回404状态),无法正常查看和使用接口文档。
相关配置文件
settings.py
from pathlib import Path BASE_DIR = Path(__file__).resolve().parent.parent SECRET_KEY = "django-insecure-rjo^&xj7pgft@ylezdg!)n_+(6k$22gme@&mxw_z!jymtv(z+g" DEBUG = True INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "api.apps.ApiConfig", "rest_framework_swagger", "rest_framework", "drf_yasg", ] SWAGGER_SETTINGS = { "SECURITY_DEFINITIONS": { "basic": { "type": "basic", } }, "USE_SESSION_AUTH": False, } REST_FRAMEWORK = { "DEFAULT_PARSER_CLASSES": [ "rest_framework.parsers.JSONParser", ] } MIDDLEWARE = [ "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", ] ROOT_URLCONF = "app.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] APPEND_SLASH = False WSGI_APPLICATION = "app.wsgi.app" # 正常情况下这些变量应该放在Vercel的环境变量文件中 DATABASES = { "default": { "ENGINE": "", "URL": "", "NAME": "", "USER": "", "PASSWORD": "", "HOST": "", "PORT": 00000, } } ALLOWED_HOSTS = ["127.0.0.1", ".vercel.app", "localhost"] # Password validation # https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] # Internationalization # https://docs.djangoproject.com/en/4.2/topics/i18n/ LANGUAGE_CODE = "en-us" TIME_ZONE = "UTC" USE_I18N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.2/howto/static-files/ STATIC_URL = "static/" # Default primary key field type # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
wsgi.py
import os from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings") app = get_wsgi_application()
URL路由配置
urlpatterns = [ path("", index), path("docs", schema_view.with_ui("swagger", cache_timeout=0)), ]
vercel.json
{ "builds": [ { "src": "build_files.sh", "use": "@vercel/static-build", "config": { "distDir": "staticfiles_build" } }, { "src": "/app/wsgi.py", "use": "@vercel/python", "config": { "maxLambdaSize": "15mb" } } ], "routes": [ { "src": "/(.*)", "dest": "app/wsgi.py" }, { "src": "/static/(.*)", "dest": "/static/$1" } ] }
错误原因及解决办法
1. Vercel路由规则顺序错误
当前vercel.json中路由规则先匹配所有请求到WSGI应用,静态文件请求也被转发到Django,导致静态资源无法被Vercel的静态托管服务处理,出现404。
解决:调整路由顺序,把静态文件规则放在前面(Vercel路由从上到下匹配):
"routes": [ { "src": "/static/(.*)", "dest": "/static/$1" }, { "src": "/(.*)", "dest": "app/wsgi.py" } ]
2. 静态文件未正确收集
Swagger的静态资源需要通过Django的collectstatic命令收集到指定目录,才能被Vercel托管。
解决:确保build_files.sh包含以下命令,并且脚本有执行权限:
#!/bin/bash python manage.py collectstatic --noinput mkdir -p staticfiles_build/static cp -r static/* staticfiles_build/static/
部署前本地执行chmod +x build_files.sh赋予执行权限,Vercel构建时会自动运行该脚本。
3. DEBUG模式与静态资源服务冲突
生产环境下DEBUG=True时,Django会自己处理静态资源,但Vercel的Serverless环境不支持这种方式,必须依赖静态托管。
解决:生产环境将DEBUG设为False,同时配置静态文件根目录:
# settings.py DEBUG = False STATIC_ROOT = BASE_DIR / 'staticfiles_build' / 'static'
4. 数据库配置为空
Django启动需要有效的数据库配置,空配置会导致内部错误,间接影响Swagger页面加载。
解决:配置至少一个可用的数据库,比如本地SQLite:
DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": BASE_DIR / "db.sqlite3", } }
生产环境可在Vercel环境变量中配置真实数据库信息。
内容的提问来源于stack exchange,提问作者Alex Ironside
相关产品推荐
相关产品推荐

