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

发布于 2024-09-26 07:35:06 字数 170 浏览 1 评论 0原文

我需要获取所有 Django 请求标头。据我所知,Django 只是将所有内容以及许多其他数据转储到 request.META 变量中。获取客户端发送到我的 Django 应用程序的所有标头的最佳方法是什么?

我将使用它们来构建 httplib 请求。

I need to get all the Django request headers. From what I've read, Django simply dumps everything into the request.META variable along with a lot of other data. What would be the best way to get all the headers that the client sent to my Django application?

I'm going use these to build a httplib request.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

拍不死你 2024-10-03 07:35:06

根据 文档 request.META 是一个“包含所有可用 HTTP 标头的标准 Python 字典”。如果您想获取所有标题,您只需迭代字典即可。

代码的哪一部分执行此操作取决于您的具体要求。任何有权访问 request 的地方都可以。

更新

我需要在中间件类中访问它,但是当我迭代它时,除了 HTTP 标头之外,我还获得了很多值。

从文档中:

除了上面给出的 CONTENT_LENGTHCONTENT_TYPE 之外,请求中的任何 HTTP 标头都会转换为 META< /code> 键,方法是将所有字符转换为大写,用下划线替换所有连字符,并在名称中添加 HTTP_ 前缀


(强调)

要单独获取 HTTP 标头,只需按前缀为 HTTP_ 的键进行过滤即可。

更新2

您能否向我展示如何通过过滤掉 request.META 变量中以 HTTP_ 开头的所有键并删除前导 HTTP_ 部分来构建标头字典。

当然。这是一种方法。

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

According to the documentation request.META is a "standard Python dictionary containing all available HTTP headers". If you want to get all the headers you can simply iterate through the dictionary.

Which part of your code to do this depends on your exact requirement. Anyplace that has access to request should do.

Update

I need to access it in a Middleware class but when i iterate over it, I get a lot of values apart from HTTP headers.

From the documentation:

With the exception of CONTENT_LENGTH and CONTENT_TYPE, as given above, any HTTP headers in the request are converted to META keys by converting all characters to uppercase, replacing any hyphens with underscores and adding an HTTP_ prefix to the name.

(Emphasis added)

To get the HTTP headers alone, just filter by keys prefixed with HTTP_.

Update 2

could you show me how I could build a dictionary of headers by filtering out all the keys from the request.META variable which begin with a HTTP_ and strip out the leading HTTP_ part.

Sure. Here is one way to do it.

import re
regex = re.compile('^HTTP_')
dict((regex.sub('', header), value) for (header, value) 
       in request.META.items() if header.startswith('HTTP_'))
你丑哭了我 2024-10-03 07:35:06

从 Django 2.2 开始,您可以使用 request.headers 来访问 HTTP 标头。来自有关 HttpRequest.headers 的文档

一个不区分大小写、类似字典的对象,提供对请求中所有带有 HTTP 前缀的标头(加上 Content-Length 和 Content-Type)的访问。

每个标题的名称在显示时都使用标题大小写(例如 User-Agent)进行样式化。您可以不区分大小写地访问标头:

<前><代码>>>>请求头
{'用户代理':'Mozilla/5.0(Macintosh;Intel Mac OS X 10_12_6',...}

>>>>> request.headers 中的“用户代理”
真的
>>>>> request.headers 中的“用户代理”
真的

>>>>> request.headers['用户代理']
Mozilla/5.0(Macintosh;英特尔 Mac OS X 10_12_6)
>>>>> request.headers['用户代理']
Mozilla/5.0(Macintosh;英特尔 Mac OS X 10_12_6)

>>>>> request.headers.get('用户代理')
Mozilla/5.0(Macintosh;英特尔 Mac OS X 10_12_6)
>>>>> request.headers.get('用户代理')
Mozilla/5.0(Macintosh;英特尔 Mac OS X 10_12_6)

要获取所有标头,您可以使用 request.headers.keys()request.headers.items()

Starting from Django 2.2, you can use request.headers to access the HTTP headers. From the documentation on HttpRequest.headers:

A case insensitive, dict-like object that provides access to all HTTP-prefixed headers (plus Content-Length and Content-Type) from the request.

The name of each header is stylized with title-casing (e.g. User-Agent) when it’s displayed. You can access headers case-insensitively:

>>> 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)

To get all headers, you can use request.headers.keys() or request.headers.items().

违心° 2024-10-03 07:35:06

这是另一种方法,与上面 Manoj Govindan 的答案非常相似:

import re
regex_http_          = re.compile(r'^HTTP_.+

这也会获取 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 除外)。

每个标头的值不应被修改。

) regex_content_type = re.compile(r'^CONTENT_TYPE

这也会获取 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 除外)。

每个标头的值不应被修改。

) regex_content_length = re.compile(r'^CONTENT_LENGTH

这也会获取 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 除外)。

每个标头的值不应被修改。

) 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 除外)。

每个标头的值不应被修改。

This is another way to do it, very similar to Manoj Govindan's answer above:

import re
regex_http_          = re.compile(r'^HTTP_.+

That will also grab the CONTENT_TYPE and CONTENT_LENGTH request headers, along with the HTTP_ ones. request_headers['some_key] == request.META['some_key'].

Modify accordingly if you need to include/omit certain headers. Django lists a bunch, but not all, of them here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

Django's algorithm for request headers:

  1. Replace hyphen - with underscore _
  2. Convert to UPPERCASE.
  3. Prepend HTTP_ to all headers in original request, except for CONTENT_TYPE and CONTENT_LENGTH.

The values of each header should be unmodified.

) regex_content_type = re.compile(r'^CONTENT_TYPE

That will also grab the CONTENT_TYPE and CONTENT_LENGTH request headers, along with the HTTP_ ones. request_headers['some_key] == request.META['some_key'].

Modify accordingly if you need to include/omit certain headers. Django lists a bunch, but not all, of them here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

Django's algorithm for request headers:

  1. Replace hyphen - with underscore _
  2. Convert to UPPERCASE.
  3. Prepend HTTP_ to all headers in original request, except for CONTENT_TYPE and CONTENT_LENGTH.

The values of each header should be unmodified.

) regex_content_length = re.compile(r'^CONTENT_LENGTH

That will also grab the CONTENT_TYPE and CONTENT_LENGTH request headers, along with the HTTP_ ones. request_headers['some_key] == request.META['some_key'].

Modify accordingly if you need to include/omit certain headers. Django lists a bunch, but not all, of them here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

Django's algorithm for request headers:

  1. Replace hyphen - with underscore _
  2. Convert to UPPERCASE.
  3. Prepend HTTP_ to all headers in original request, except for CONTENT_TYPE and CONTENT_LENGTH.

The values of each header should be unmodified.

) 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]

That will also grab the CONTENT_TYPE and CONTENT_LENGTH request headers, along with the HTTP_ ones. request_headers['some_key] == request.META['some_key'].

Modify accordingly if you need to include/omit certain headers. Django lists a bunch, but not all, of them here: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META

Django's algorithm for request headers:

  1. Replace hyphen - with underscore _
  2. Convert to UPPERCASE.
  3. Prepend HTTP_ to all headers in original request, except for CONTENT_TYPE and CONTENT_LENGTH.

The values of each header should be unmodified.

菩提树下叶撕阳。 2024-10-03 07:35:06

只需使用 HttpRequest.headersDjango 2.2 开始。以下示例直接取自 Django 文档 下的 请求和响应对象部分。

>>> 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)

Simply you can use HttpRequest.headers from Django 2.2 onward. Following example is directly taken from the official Django Documentation under Request and response objects section.

>>> 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)
云巢 2024-10-03 07:35:06

request.META.get('HTTP_AUTHORIZATION')
/python3.6/site-packages/rest_framework/authentication.py

你可以从这个文件中得到它......

request.META.get('HTTP_AUTHORIZATION')
/python3.6/site-packages/rest_framework/authentication.py

you can get that from this file though...

唯憾梦倾城 2024-10-03 07:35:06

我认为没有任何简单的方法可以只获取 HTTP 标头。您必须迭代 request.META 字典才能获得您需要的所有内容。

django-debug-toolbar 采用相同的方法来显示标头信息。看看这个文件 负责检索标头信息。

I don't think there is any easy way to get only HTTP headers. You have to iterate through request.META dict to get what all you need.

django-debug-toolbar takes the same approach to show header information. Have a look at this file responsible for retrieving header information.

盛夏已如深秋| 2024-10-03 07:35:06

如果您想从请求标头获取客户端密钥,您可以尝试以下操作:

from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from apps.authentication.models import CerebroAuth

class CerebroAuthentication(BaseAuthentication):
def authenticate(self, request):
    client_id = request.META.get('HTTP_AUTHORIZATION')
    if not client_id:
        raise exceptions.AuthenticationFailed('Client key not provided')
    client_id = client_id.split()
    if len(client_id) == 1 or len(client_id) > 2:
        msg = ('Invalid secrer key header. No credentials provided.')
        raise exceptions.AuthenticationFailed(msg)
    try:
        client = CerebroAuth.objects.get(client_id=client_id[1])
    except CerebroAuth.DoesNotExist:
        raise exceptions.AuthenticationFailed('No such client')
    return (client, None)

If you want to get client key from request header, u can try following:

from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from apps.authentication.models import CerebroAuth

class CerebroAuthentication(BaseAuthentication):
def authenticate(self, request):
    client_id = request.META.get('HTTP_AUTHORIZATION')
    if not client_id:
        raise exceptions.AuthenticationFailed('Client key not provided')
    client_id = client_id.split()
    if len(client_id) == 1 or len(client_id) > 2:
        msg = ('Invalid secrer key header. No credentials provided.')
        raise exceptions.AuthenticationFailed(msg)
    try:
        client = CerebroAuth.objects.get(client_id=client_id[1])
    except CerebroAuth.DoesNotExist:
        raise exceptions.AuthenticationFailed('No such client')
    return (client, None)
Oo萌小芽oO 2024-10-03 07:35:06

就其价值而言,您的意图似乎是使用传入的 HTTP 请求来形成另一个 HTTP 请求。有点像网关。有一个出色的模块 django-revproxy 可以完全实现这一点。

该来源是关于如何完成您想要做的事情的一个很好的参考。

For what it's worth, it appears your intent is to use the incoming HTTP request to form another HTTP request. Sort of like a gateway. There is an excellent module django-revproxy that accomplishes exactly this.

The source is a pretty good reference on how to accomplish what you are trying to do.

゛清羽墨安 2024-10-03 07:35:06

请注意在标头密钥中使用“-”而不是“_”,

因为如果您在标头中使用“Current_User”,则无法通过

request.headers.get('Current_User')   <-- None

用户“xxx-xxx”作为密钥来获取它

Just be aware to use "-" instead of "_" in header Key

Because if you use "Current_User" in header, you can not get it by

request.headers.get('Current_User')   <-- None

user "xxx-xxx" as the key

最舍不得你 2024-10-03 07:35:06
<b>request.META</b><br>
{% for k_meta, v_meta in request.META.items %}
  <code>{{ k_meta }}</code> : {{ v_meta }} <br>
{% endfor %}
<b>request.META</b><br>
{% for k_meta, v_meta in request.META.items %}
  <code>{{ k_meta }}</code> : {{ v_meta }} <br>
{% endfor %}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文