Djangoですべてのリクエストヘッダーを取得するにはどうすればよいですか?


107

すべてのDjangoリクエストヘッダーを取得する必要があります。私が読んだことから、Djangoはrequest.META他の多くのデータと一緒にすべてを単に変数にダンプします。クライアントがDjangoアプリケーションに送信したすべてのヘッダーを取得する最良の方法は何ですか?

これらを使用してhttplibリクエストを作成します。

回答:


139

ドキュメントに よるrequest.METAと、「利用可能なすべてのHTTPヘッダーを含む標準のPython辞書」です。すべてのヘッダーを取得たい場合は、辞書を反復処理するだけです。

これを行うコードの部分は、正確な要件によって異なります。アクセスできる場所requestならどこでもいい。

更新

ミドルウェアクラスでアクセスする必要がありますが、繰り返し処理すると、HTTPヘッダー以外にも多くの値が表示されます。

ドキュメントから:

上記のようにCONTENT_LENGTHandを除いて、リクエスト内のCONTENT_TYPEすべてのHTTPヘッダーは、METAすべての文字を大文字に変換し、ハイフンをアンダースコアに置き換え、名前にプレフィックスを追加することHTTP_によってキーに変換されます。

(エンファシスを追加)

HTTPヘッダーのみを取得するには、プレフィックスがのキーでフィルタリングしますHTTP_

アップデート2

HTTP_で始まるrequest.META変数からすべてのキーを除外し、先頭のHTTP_の部分を取り除くことで、ヘッダーのディクショナリーを構築する方法を教えてください。

承知しました。これを行う1つの方法を次に示します。

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

Middlewareクラスでアクセスする必要がありますが、繰り返し処理すると、HTTPヘッダー以外にも多くの値が表示されます。
Mridang Agarwalla

Manojに感謝します。ちょうど好奇心からrequest.META-aで始まる変数からすべてのキーを除外してヘッダーの辞書を作成HTTP_し、先頭のHTTP_部分を取り除く方法を教えていただけませんか。これはラムダ関数を通じて可能ですか?(私はそれらをラムダ関数と呼んでいると思います)私はおそらく最初にそれらを反復し、それがaで始まるかどうかを確認しHTTP_てから新しい辞書に追加することで長い道のりをたどるので、これを求めています 再度、感謝します。
Mridang Agarwalla

Manojに感謝します。lstrip('HTTP_')正規表現の代わりに使用するように少し修正しました。:)
Mridang Agarwalla

3
@Mridang Agarwalla:lstrip実際にあなたがやろうとしていることはしません。 lstripあなたは、ヘッダーを持っている場合ので、あなたはそれを与える文字列内の任意の文字に一致するすべての主要な文字を取り除くだろう"HTTP_TOKEN_ID"、それはお返しします"OKEN_ID"ので、"T"の初めに"TOKEN"マッチlstripに渡された文字列内の文字。それをする方法はprefix = 'HTTP_'; header = header[len(prefix):]です。
jcdyer 2014

2
Django 2.2がサポートしていHttpRequest.headersます。
Dcalsky、

30

Django 2.2以降では、を使用request.headersしてHTTPヘッダーにアクセスできます。HttpRequest.headersドキュメントから:

リクエストからすべてのHTTP接頭辞付きヘッダー(およびContent-LengthとContent-Type)へのアクセスを提供する、大文字と小文字を区別しない、dictのようなオブジェクト。

各ヘッダーの名前は、表示されるときにタイトルケース(例: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()


17

これは別の方法で、上記の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_TYPEおよびCONTENT_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

各ヘッダーの値は変更しないでください。


5
それはすべて、単一の正規表現に組み合わせることができるre.compile(r'^(HTTP_.+|CONTENT_TYPE|CONTENT_LENGTH)$')
Rebs


3

HTTPヘッダーのみを取得する簡単な方法はないと思います。必要なものをすべて取得するには、request.META dictを反復処理する必要があります。

django-debug-toolbarも同じ方法でヘッダー情報を表示します。見てい、このファイルのヘッダー情報を取得するための責任を。


1

リクエストヘッダーからクライアントキーを取得したい場合は、以下を試すことができます:

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)

1

価値があることについては、あなたの意図は、着信HTTP要求を使用して別のHTTP要求を形成することであると思われます。ゲートウェイのようなものです。これを正確に実行する優れたモジュールdjango-revproxyがあります。

ソースは、あなたがやろうとしていることを達成する方法についてのかなり良いリファレンスです。


0
<b>request.META</b><br>
{% for k_meta, v_meta in request.META.items %}
  <code>{{ k_meta }}</code> : {{ v_meta }} <br>
{% endfor %}

0

単にDjango 2.2以降のHttpRequest.headersを使用できます。次の例は、リクエストオブジェクトとレスポンスオブジェクトのセクションにある公式の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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.