Django中获取含下划线(_)的请求Header值的正确方式
在Django中获取含下划线的自定义Header的正确方式
你遇到的这个问题其实和WSGI服务器对HTTP请求头的处理规则有关,我来给你拆解下原因和解决办法:
为什么request.META['HTTP_CLIENT_CDATA']会报错?
WSGI规范(Django底层依赖的Web服务器接口)默认认为HTTP请求头名称里的下划线是非法字符,大多数WSGI服务器(比如Gunicorn、uWSGI、Apache)会直接丢弃包含下划线的请求头,或者对其进行特殊转换(比如移除下划线),这就导致你在request.META里找不到对应的HTTP_CLIENT_CDATA键,从而抛出KeyError。
而你能成功获取clientdata的值,是因为这个Header名称里没有下划线,WSGI服务器正常将它转换为HTTP_CLIENTDATA存入request.META。
解决办法
方法1:使用request.headers直接获取(推荐)
从Django 2.2版本开始,框架提供了request.headers这个更友好的对象,它直接映射原始的HTTP请求头,不区分大小写,也不需要额外添加HTTP_前缀。你可以直接用原始的Header名称来获取值:
# 直接用原始的header名称,大小写不敏感 client_cdata_value = request.headers.get('client_cdata') # 或者也可以写成不区分大小写的形式 client_cdata_value = request.headers.get('Client_Cdata')
这种方法不需要修改任何服务器配置,也不受WSGI对下划线的限制,最适合你这种无法修改客户端请求的场景。
方法2:修改WSGI服务器配置(仅当你有权限修改服务器时)
如果你必须使用request.META来获取,那需要配置你的WSGI服务器允许请求头中包含下划线:
- Gunicorn:启动时添加
--enable-underscores参数 - uWSGI:在配置文件中设置
underscores-in-headers = true - Apache:修改配置文件,添加规则将自定义Header映射到
request.META中,比如SetEnvIfNoCase ^client_cdata$ "(.+)" HTTP_CLIENT_CDATA=$1
配置完成后,你就可以用request.META['HTTP_CLIENT_CDATA']来获取对应的值了,但这种方法需要你有权限修改服务器设置,不如第一种方法灵活。
内容的提问来源于stack exchange,提问作者Mr Singh
相关产品推荐
相关产品推荐

