Django Rest Framework部署后OPTIONS请求丢失Strict-Transport-Security头求助
问题分析与解决方案
核心原因推测
部署环境中,OPTIONS请求大概率被前端代理(如Nginx、Apache)或Django的CORS中间件提前拦截并直接返回响应,导致你的自定义中间件根本没机会处理这类请求的响应。本地测试时通常没有额外代理,或代理配置宽松,所以中间件能正常作用于所有请求类型。
排查思路
- 检查部署Web服务器配置:比如Nginx是否有针对OPTIONS请求的特殊规则,比如直接返回200响应而不转发到Django应用,这类响应不会经过你的中间件。
- 核对中间件执行顺序:如果用了
django-cors-headers的CorsMiddleware,它可能在你的自定义中间件之前执行,并且会直接生成OPTIONS请求的响应,导致你的中间件无法修改这个响应。 - 查看
DEBUG模式差异:部署环境通常关闭DEBUG,Django或部分中间件在DEBUG=False时会有不同的请求处理逻辑,比如OPTIONS请求的流转路径变化。
解决建议
方案1:调整中间件顺序
确保你的AddStrictTransportSecurityHeaderMiddleware排在所有CORS相关中间件之前,让它优先处理响应。修改settings.py的MIDDLEWARE列表:
MIDDLEWARE = [ # 把你的自定义中间件放在最前或CORS中间件之前 'yourapp.middleware.AddStrictTransportSecurityHeaderMiddleware', 'corsheaders.middleware.CorsMiddleware', # 其他中间件... ]
方案2:在Web服务器层面添加HSTS头
如果代理服务器直接处理OPTIONS请求,在代理配置中全局添加HSTS头更可靠。以Nginx为例,在server块中配置:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
加上always参数能确保所有响应(包括OPTIONS)都携带该头。
方案3:利用Django内置HSTS配置
Django本身提供了HSTS的内置支持,直接在settings.py中配置即可,由SecurityMiddleware自动处理所有响应:
SECURE_HSTS_SECONDS = 31536000 SECURE_HSTS_INCLUDE_SUBDOMAINS = True
注意要确保SecurityMiddleware存在于MIDDLEWARE列表中,且顺序合理。
方案4:增强自定义中间件的兼容性
如果坚持用自定义中间件,可以额外重写process_response方法,确保OPTIONS请求的响应被处理:
class AddStrictTransportSecurityHeaderMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) response['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains' return response def process_response(self, request, response): if request.method == 'OPTIONS': response['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains' return response
内容的提问来源于stack exchange,提问作者Abdul Rahman.
相关产品推荐
相关产品推荐

