服务端调试Django出现Not Acceptable报错如何查看客户端请求头
解决方案
方案1:新增前置自定义中间件(优先推荐)
请求未到视图层通常是被Django的中间件(如CommonMiddleware、内容协商相关中间件)提前拦截,将自定义中间件放到最高优先级即可捕获所有进入Django的请求头:
- 在对应APP下新建
middleware.py,写入如下代码:
import logging from django.utils.deprecation import MiddlewareMixin logger = logging.getLogger(__name__) class CaptureAllHeadersMiddleware(MiddlewareMixin): def process_request(self, request): # 筛选所有HTTP请求头,Django会自动将请求头转为大写、加HTTP_前缀存入request.META headers = { k: v for k, v in request.META.items() if k.startswith("HTTP_") or k in ("CONTENT_TYPE", "CONTENT_LENGTH") } # 日志输出对应请求路径和头信息,方便匹配故障请求 logger.warning(f"Path {request.path} request headers: {headers}") # 不拦截请求,继续向后执行 return None
- 在
settings.py的MIDDLEWARE列表最顶部注册该中间件,确保它是第一个执行的中间件:
MIDDLEWARE = [ "你的APP名称.middleware.CaptureAllHeadersMiddleware", # 原有中间件保持原有顺序不变 ... ]
- 复现故障请求后,查看Django服务日志即可找到对应请求的完整头信息,其中
HTTP_ACCEPT字段就是客户端发送的Accept头取值。
方案2:临时调整Django请求日志级别
如果不想新增代码,可临时调高django.request日志级别到DEBUG,部分Django版本会在406错误日志中附带完整请求上下文:
在settings.py中添加日志配置:
LOGGING = { "version": 1, "disable_existing_loggers": False, "loggers": { "django.request": { "level": "DEBUG", "handlers": ["console"], # 对应你已配置的日志handler名称 "propagate": True, } } }
方案3:DRF接口特殊处理
如果该接口是基于Django REST Framework开发,406错误可能是DRF的内容协商层拦截导致,可临时修改自定义异常处理函数打印请求头:
from rest_framework.views import exception_handler import logging logger = logging.getLogger(__name__) def custom_exception_handler(exc, context): response = exception_handler(exc, context) if response and response.status_code == 406: request = context["request"] headers = {k:v for k,v in request.META.items() if k.startswith("HTTP_")} logger.warning(f"406 error for {request.path}, headers: {headers}") return response
在settings.py中配置启用该异常处理:
REST_FRAMEWORK = { "EXCEPTION_HANDLER": "你的模块路径.custom_exception_handler" }
拿到请求头后,对比正常请求(Postman/curl)的Accept头和故障客户端的Accept头,调整服务端内容协商支持的MIME类型,或通知客户端修正Accept头即可解决406问题。
内容的提问来源于stack exchange,提问作者DIJ
相关产品推荐
相关产品推荐

