Django request.META.get()获取不到header头的原因分析
在Django开发中,通过request.META.get()获取不到自定义header是常见问题。本文详细解析其根本原因:Django会自动将HTTP请求头转换为大写并替换连字符为下划线,且必须添加HTTP_前缀。例如,auth-token需转换为HTTP_AUTH_TOKEN。文章还对比了URL参数、查询字符串、表单及原始请求体的获取方式,帮助开发者全面掌握Django的请求处理机制。
为什么 request.META.get() 获取不到 header?
在 Django API 开发中,验证信息通常放置在 HTTP 请求的 header 中。然而,直接使用 request.META.get("headerkey") 往往无法获取到预期的值。这主要是因为 Django 对 HTTP 请求头进行了特定的处理:
- 前缀添加:Django 会自动为所有 HTTP 请求头添加
HTTP前缀。 - 格式转换:请求头中的连字符(
-)会被转换为下划线(_),且整个键名会被转换为大写。 - 命名规范:因此,自定义的 header 键名不应包含
HTTP前缀及下划线。
例如,如果客户端发送的 header 键名为 auth-token,在 Django 的 request.META 中,其对应的键名应为 HTTP_AUTH_TOKEN。
Django 获取 HTTP 参数的多种途径
HTTP 协议向服务器传递参数有多种方式,Django 提供了不同的属性来分别处理这些数据。了解这些区别有助于正确获取所需信息。
1. URL 参数
URL 参数可以通过正则表达式提取。未命名参数按定义顺序传递,不可互换;命名参数则按名字传递,位置可互换。
url(r'^users/([a-z]+)/(\d{4})/$', views.get_user),
def get_user(request, name, ID):
print('name=%s' % name)
print('id=%s' % id)
return HttpResponse('OK')url(r'^users/(?P<name>[a-z]+)/(?P<id>\d{4})/$', views.users),
def weather(request, name, id):
print('name=%s' % name)
print('id=%s' % id)
return HttpResponse('OK')2. 查询字符串 (Query String)
查询字符串通过 request.GET 获取,返回一个 QueryDict 对象。该对象处理同一键带多个值的情况:
get('key'):获取键的最后一个值,若不存在则返回None。getlist('key'):获取指定键的所有值,返回列表。
查询字符串不区分 GET 或 POST 请求方式。
url(r'^qs/$',views.get_value,name='g_v'),
def get_value(request):
a = request.GET.get('a') #3
b = request.GET.get('b') #2
num_list = request.GET.getlist('a') #['1','3']
print(a)
print(b)
print(num_list)
return HttpResponse(reverse('user:get_value'))3. 表单数据 (Form Data)
表单数据通过 request.POST 获取。需要注意的是,Django 默认开启 CSRF 防护,在测试时可能需要暂时关闭。
url(r'^getbody/$',views.get_body),
def get_body(request):
form_data = request.POST.get('c')
print(form_data)
return HttpResponse(form_data)4. 原始请求体 (Request Body)
非表单数据(如 JSON、XML)通过 request.body 获取,返回原始的二进制数据(bytes)。开发者需自行按格式解析。
import json
url(r'^getjson/$',views.get_body_json),
def get_body_json(request):
# 得到的是一个二进制数据
json_str = request.body
print(json_str) # b'{\n "f":200,\n "d":300\n \n}'\
# 对二进制数据进行解码,解码得到json数据
json_str = json_str.decode()
print(json_str) # {"f":200,"d":300}
# 将json数据转化成字典形式
json_data = json.loads(json_str)
print(json_data) # {'f': 200, 'd': 300}
# 获取json数据,使用字典方式取值
print(json_data['d']) # 300
print(json_data['f']) # 200
return HttpResponse('ok')5. 其他请求属性
Django 还提供了其他常用属性来获取请求的元数据:
request.method:获取请求方式(如 GET, POST)。request.path:获取请求路径。request.user:获取当前请求的用户对象。request.FILES:包含所有上传的文件。request.encoding:表示请求页面完整路径,默认为浏览器的默认设置(通常为 utf-8),该属性可写,用于修改编码。
url(r'^otherattr/$', views.other_attr),
def other_attr(request):
print(request.method) # POST
print(request.path) # /user/otherattr/
print(request.encoding) # None:表示使用浏览器的默认设置,一般为utf-8,这个属性是可写的,
# 可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
总结
在 Django 中获取 header 时,务必注意 HTTP_ 前缀以及连字符转下划线的规则。同时,根据数据来源的不同(URL、查询字符串、表单、原始体),选择正确的获取方式。以上就是 Django request.META.get()获取不到header头的原因分析的详细内容,更多关于Django请求处理机制的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













