Wie kann ich alle Anforderungsheader in Django abrufen?
107
Ich muss alle Django-Anforderungsheader erhalten. request.METANach dem, was ich gelesen habe, legt Django einfach alles zusammen mit vielen anderen Daten in der Variablen ab. Was wäre der beste Weg, um alle Header zu erhalten, die der Client an meine Django-Anwendung gesendet hat?
Ich werde diese verwenden, um eine httplibAnfrage zu erstellen .
Der Dokumentation zufolge request.METAhandelt es sich um ein "Standard-Python-Wörterbuch, das alle verfügbaren HTTP-Header enthält". Wenn Sie alle Header erhalten möchten, können Sie einfach das Wörterbuch durchlaufen.
Welcher Teil Ihres Codes dies tut, hängt von Ihrer genauen Anforderung ab. Jeder Ort, zu dem Zugang besteht, requestsollte dies tun.
Aktualisieren
Ich muss in einer Middleware-Klasse darauf zugreifen, aber wenn ich darüber iteriere, erhalte ich neben HTTP-Headern viele Werte.
Aus der Dokumentation:
Mit Ausnahme von CONTENT_LENGTHund CONTENT_TYPE, wie oben angegeben, werden alle HTTPÜberschriften in der Anforderung in METASchlüssel konvertiert, indem alle Zeichen in Großbuchstaben konvertiert, Bindestriche durch Unterstriche ersetzt und dem Namen ein HTTP_Präfix hinzugefügt werden .
(Betonung hinzugefügt)
Um die HTTPHeader alleine zu erhalten, filtern Sie einfach nach Schlüsseln, denen ein Präfix vorangestellt ist HTTP_.
Update 2
Können Sie mir zeigen, wie ich ein Wörterbuch mit Headern erstellen kann, indem ich alle Schlüssel aus der request.META-Variablen herausfiltere, die mit einem HTTP_ beginnen und den führenden HTTP_-Teil entfernen.
Ich muss in einer Middleware-Klasse darauf zugreifen, aber wenn ich darüber iteriere, erhalte ich neben HTTP-Headern viele Werte.
Mridang Agarwalla
Danke Manoj. Nur aus Neugier - können Sie mir zeigen, wie ich ein Wörterbuch mit Überschriften erstellen kann, indem Sie alle Schlüssel aus der request.METAVariablen HTTP_herausfiltern, die mit a beginnen, und den führenden HTTP_Teil entfernen . Ist dies durch Lambda-Funktionen möglich? (Ich denke, sie heißen Lambda-Funktionen.) Ich frage dies, weil ich es wahrscheinlich auf lange Sicht tun würde, indem ich zuerst über sie iteriere, dann überprüfe, ob es mit a beginnt, HTTP_und es dann dem neuen Wörterbuch hinzufüge. Danke noch einmal.
Mridang Agarwalla
Nochmals vielen Dank Manoj. Ich habe es leicht modifiziert, um es lstrip('HTTP_')anstelle des regulären Ausdrucks zu verwenden. :)
Mridang Agarwalla
3
@ Mridang Agarwalla: Ich lstripwerde nicht das tun, was du von ihm verlangst . lstripEntfernt alle führenden Zeichen, die mit den Zeichen in der von Ihnen angegebenen Zeichenfolge übereinstimmen. Wenn Sie also eine Kopfzeile "HTTP_TOKEN_ID"haben, wird diese zurückgegeben "OKEN_ID", da "T"zu Beginn "TOKEN"ein Zeichen in der Zeichenfolge übereinstimmt, das an lstrip übergeben wurde. Der Weg dazu ist prefix = 'HTTP_'; header = header[len(prefix):].
Ein Objekt ohne Berücksichtigung der Groß- und Kleinschreibung, das Zugriff auf alle Header mit HTTP-Präfix (plus Inhaltslänge und Inhaltstyp) aus der Anforderung bietet.
Der Name jedes Headers wird bei der Anzeige mit einem Titel (z. B. User-Agent) stilisiert. Sie können unabhängig von Groß- und Kleinschreibung auf Header zugreifen:
>>> 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;IntelMac OS X 10_12_6)>>> request.headers['user-agent']Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)>>> request.headers.get('User-Agent')Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)>>> request.headers.get('user-agent')Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)
Um alle Header zu erhalten, können Sie request.headers.keys()oder verwenden request.headers.items().
Dadurch werden auch die Header abgerufen CONTENT_TYPEund CONTENT_LENGTHangefordert, zusammen mit HTTP_denen. request_headers['some_key]== request.META['some_key'].
Ich glaube nicht, dass es einen einfachen Weg gibt, nur HTTP-Header zu bekommen. Sie müssen die Anfrage durchlaufen. META-Diktat, um alles zu bekommen, was Sie brauchen.
Die django-debug-Symbolleiste verwendet denselben Ansatz, um Header-Informationen anzuzeigen. Schauen Sie sich diese Datei an, die für das Abrufen von Header-Informationen verantwortlich ist.
Es scheint, dass Sie beabsichtigen, die eingehende HTTP-Anforderung zu verwenden, um eine weitere HTTP-Anforderung zu bilden. Irgendwie wie ein Gateway. Es gibt ein exzellentes Modul django-revproxy , das genau dies erreicht.
Die Quelle ist eine ziemlich gute Referenz dafür, wie Sie das erreichen, was Sie versuchen.
>>> 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;IntelMac OS X 10_12_6)>>> request.headers['user-agent']Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)>>> request.headers.get('User-Agent')Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)>>> request.headers.get('user-agent')Mozilla/5.0(Macintosh;IntelMac OS X 10_12_6)
request.META
VariablenHTTP_
herausfiltern, die mit a beginnen, und den führendenHTTP_
Teil entfernen . Ist dies durch Lambda-Funktionen möglich? (Ich denke, sie heißen Lambda-Funktionen.) Ich frage dies, weil ich es wahrscheinlich auf lange Sicht tun würde, indem ich zuerst über sie iteriere, dann überprüfe, ob es mit a beginnt,HTTP_
und es dann dem neuen Wörterbuch hinzufüge. Danke noch einmal.lstrip('HTTP_')
anstelle des regulären Ausdrucks zu verwenden. :)lstrip
werde nicht das tun, was du von ihm verlangst .lstrip
Entfernt alle führenden Zeichen, die mit den Zeichen in der von Ihnen angegebenen Zeichenfolge übereinstimmen. Wenn Sie also eine Kopfzeile"HTTP_TOKEN_ID"
haben, wird diese zurückgegeben"OKEN_ID"
, da"T"
zu Beginn"TOKEN"
ein Zeichen in der Zeichenfolge übereinstimmt, das an lstrip übergeben wurde. Der Weg dazu istprefix = 'HTTP_'; header = header[len(prefix):]
.HttpRequest.headers
.Ab Django 2.2 können Sie
request.headers
auf die HTTP-Header zugreifen. Aus der Dokumentation zu HttpRequest.headers :Um alle Header zu erhalten, können Sie
request.headers.keys()
oder verwendenrequest.headers.items()
.quelle
Dies ist eine andere Möglichkeit, die der obigen Antwort von Manoj Govindan sehr ähnlich ist :
Dadurch werden auch die Header abgerufen
CONTENT_TYPE
undCONTENT_LENGTH
angefordert, zusammen mitHTTP_
denen.request_headers['some_key]
==request.META['some_key']
.Ändern Sie entsprechend, wenn Sie bestimmte Header einschließen / weglassen müssen. Django listet hier einige, aber nicht alle auf: https://docs.djangoproject.com/de/dev/ref/request-response/#django.http.HttpRequest.META
Djangos Algorithmus für Anforderungsheader:
-
durch einen Unterstrich_
HTTP_
alle Header in der ursprünglichen Anforderung mit Ausnahme vonCONTENT_TYPE
und voranCONTENT_LENGTH
.Die Werte der einzelnen Header sollten unverändert bleiben.
quelle
re.compile(r'^(HTTP_.+|CONTENT_TYPE|CONTENT_LENGTH)$')
request.META.get ('HTTP_AUTHORIZATION')
/python3.6/site-packages/rest_framework/authentication.py
Sie können das aber aus dieser Datei bekommen ...
quelle
Ich glaube nicht, dass es einen einfachen Weg gibt, nur HTTP-Header zu bekommen. Sie müssen die Anfrage durchlaufen. META-Diktat, um alles zu bekommen, was Sie brauchen.
Die django-debug-Symbolleiste verwendet denselben Ansatz, um Header-Informationen anzuzeigen. Schauen Sie sich diese Datei an, die für das Abrufen von Header-Informationen verantwortlich ist.
quelle
Wenn Sie den Clientschlüssel aus dem Anforderungsheader abrufen möchten, können Sie Folgendes versuchen:
quelle
Es scheint, dass Sie beabsichtigen, die eingehende HTTP-Anforderung zu verwenden, um eine weitere HTTP-Anforderung zu bilden. Irgendwie wie ein Gateway. Es gibt ein exzellentes Modul django-revproxy , das genau dies erreicht.
Die Quelle ist eine ziemlich gute Referenz dafür, wie Sie das erreichen, was Sie versuchen.
quelle
quelle
Sie können einfach HttpRequest.headers ab Django 2.2 verwenden . Das folgende Beispiel stammt direkt aus der offiziellen Django-Dokumentation im Abschnitt Anforderungs- und Antwortobjekte .
quelle