如何在Django中获取所有请求头?

144 投票
10 回答
184558 浏览
提问于 2025-04-16 05:12

我需要获取所有的Django请求头。从我了解到的情况来看,Django会把所有的请求信息都放到一个叫做request.META的变量里,还有很多其他的数据。那么,获取客户端发送给我的Django应用的所有请求头的最佳方法是什么呢?

我打算用这些请求头来构建一个httplib请求。

10 个回答

19

这是一种类似于Manoj Govindan上面提到的方法:

import re
regex_http_          = re.compile(r'^HTTP_.+$')
regex_content_type   = re.compile(r'^CONTENT_TYPE$')
regex_content_length = re.compile(r'^CONTENT_LENGTH$')

request_headers = {}
for header in request.META:
    if regex_http_.match(header) or regex_content_type.match(header) or regex_content_length.match(header):
        request_headers[header] = request.META[header]

这个方法也会获取到请求中的CONTENT_TYPECONTENT_LENGTH这两个头信息,还有HTTP_开头的那些。你可以把request_headers['some_key']看作是request.META['some_key']

如果你需要添加或去掉某些头信息,可以相应地进行修改。Django列出了一些头信息,但不是全部,可以在这里查看:https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

Django处理请求头信息的步骤:

  1. 把连字符-替换成下划线_
  2. 把字母转换成大写。
  3. 在原始请求的所有头信息前加上HTTP_,但CONTENT_TYPECONTENT_LENGTH除外。

每个头信息的值都应该保持不变。

67

从Django 2.2开始,你可以通过 request.headers 来获取HTTP头信息。根据HttpRequest.headers的文档

这是一个不区分大小写的字典样的对象,可以让你访问请求中的所有以HTTP开头的头信息(还有Content-Length和Content-Type)。

每个头的名字在显示时都是首字母大写的格式(比如User-Agent)。你可以不区分大小写地访问这些头信息:

>>> request.headers
{'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6', ...}

>>> 'User-Agent' in request.headers
True
>>> 'user-agent' in request.headers
True

>>> request.headers['User-Agent']
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers['user-agent']
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

>>> request.headers.get('User-Agent')
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers.get('user-agent')
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

如果你想获取所有的头信息,可以使用 request.headers.keys() 或者 request.headers.items()

175

根据文档request.META 是一个“标准的 Python 字典,包含所有可用的 HTTP 头信息”。如果你想获取所有的头信息,可以简单地遍历这个字典。

在你的代码中,具体在哪一部分执行这个操作取决于你的需求。只要能访问到request的地方都可以。

更新

我需要在一个中间件类中访问它,但当我遍历时,除了 HTTP 头信息,我还得到了很多其他的值。

根据文档:

除了上面提到的CONTENT_LENGTHCONTENT_TYPE,请求中的任何HTTP 头信息都会被转换为META 键,转换的方式是将所有字符转换为大写,把连字符替换为下划线,并在名称前加上一个HTTP_前缀

(强调部分)

如果你只想获取HTTP 头信息,只需筛选出以HTTP_开头的键。

更新 2

你能告诉我怎么做一个字典,过滤掉所有以 HTTP_ 开头的 request.META 变量中的键,并去掉前面的 HTTP_ 部分吗?

当然可以。这是一个实现的方法。

import re
regex = re.compile('^HTTP_')
dict((regex.sub('', header), value) for (header, value) 
       in request.META.items() if header.startswith('HTTP_'))

撰写回答