Jak mogę uzyskać wszystkie nagłówki żądań w Django?
107
Muszę pobrać wszystkie nagłówki żądań Django. Z tego, co przeczytałem, Django po prostu zrzuca wszystko do request.METAzmiennej wraz z wieloma innymi danymi. Jaki byłby najlepszy sposób na pobranie wszystkich nagłówków, które klient wysłał do mojej aplikacji Django?
Zgodnie z dokumentacjąrequest.META jest to „standardowy słownik Pythona zawierający wszystkie dostępne nagłówki HTTP”. Jeśli chcesz uzyskać wszystkie nagłówki, możesz po prostu przejść przez słownik.
To, która część kodu ma to zrobić, zależy od dokładnych wymagań. Każde miejsce, do którego ma dostęp, requestpowinno wystarczyć.
Aktualizacja
Muszę uzyskać do niego dostęp w klasie Middleware, ale kiedy iteruję nad nim, otrzymuję wiele wartości oprócz nagłówków HTTP.
Z dokumentacji:
Z wyjątkiem CONTENT_LENGTHi CONTENT_TYPE, jak podano powyżej, wszystkie HTTPnagłówki w żądaniu są konwertowane na METAklucze, konwertując wszystkie znaki na wielkie litery, zastępując wszelkie łączniki podkreśleniami i dodając HTTP_przedrostek do nazwy .
(Podkreślenie dodane)
Aby uzyskać HTTPsame nagłówki, po prostu przefiltruj według kluczy z prefiksem HTTP_.
Zaktualizuj 2
czy możesz mi pokazać, jak mogę zbudować słownik nagłówków, odfiltrowując wszystkie klucze ze zmiennej request.META, które zaczynają się od HTTP_ i usuwają wiodącą część HTTP_.
Muszę uzyskać do niego dostęp w klasie Middleware, ale kiedy iteruję nad nim, otrzymuję wiele wartości oprócz nagłówków HTTP.
Mridang Agarwalla
Dzięki Manoj. Tak z ciekawości - czy mógłbyś mi pokazać, jak mogę zbudować słownik nagłówków, odfiltrowując wszystkie klucze ze request.METAzmiennej, która zaczyna się od a HTTP_i usuwając wiodącą HTTP_część. Czy jest to możliwe dzięki funkcjom lambda? (Myślę, że nazywają się funkcjami lambda) Pytam o to, ponieważ prawdopodobnie zrobiłbym to długo, najpierw iterując po nich, a następnie sprawdzając, czy zaczyna się od a, HTTP_a następnie dodając go do nowego słownika. Dzięki jeszcze raz.
Mridang Agarwalla
Jeszcze raz dziękuję Manoj. Zmodyfikowałem go nieznacznie, aby użyć lstrip('HTTP_')zamiast wyrażenia regularnego. :)
Mridang Agarwalla
3
@Mridang Agarwalla: lstriptak naprawdę nie zrobi tego, o co go prosisz. lstripusunie wszystkie początkowe znaki, które pasują do dowolnych znaków w ciągu, który mu podasz, więc jeśli masz nagłówek "HTTP_TOKEN_ID", zwróci "OKEN_ID", ponieważ "T"na początku "TOKEN"dopasowania znak w ciągu przekazany do lstrip. Sposób na to jest prefix = 'HTTP_'; header = header[len(prefix):].
Obiekt podobny do dyktowania bez rozróżniania wielkości liter, który zapewnia dostęp do wszystkich nagłówków z prefiksem HTTP (plus Content-Length i Content-Type) z żądania.
Nazwa każdego nagłówka jest stylizowana na wielkość liter (np. User-Agent), gdy jest wyświetlana. Możesz uzyskać dostęp do nagłówków bez rozróżniania wielkości liter:
>>> request.headers{'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6',...}>>>'User-Agent'in request.headersTrue>>>'user-agent'in request.headersTrue>>> 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)
Aby uzyskać wszystkie nagłówki, możesz użyć request.headers.keys()lub request.headers.items().
Nie sądzę, aby istniał łatwy sposób na uzyskanie tylko nagłówków HTTP. Musisz iterować poprzez request.META dyktuje, aby uzyskać wszystko, czego potrzebujesz.
django-debug-toolbar stosuje to samo podejście do wyświetlania informacji w nagłówku. Spójrz na ten plik odpowiedzialny za pobieranie informacji z nagłówka.
Wydaje się, że Twoim zamiarem jest użycie przychodzącego żądania HTTP do utworzenia kolejnego żądania HTTP. Coś jak brama. Istnieje doskonały moduł django-revproxy, który dokładnie to robi .
Źródło jest całkiem dobrym źródłem informacji o tym, jak osiągnąć to, co próbujesz zrobić.
>>> 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
zmiennej, która zaczyna się od aHTTP_
i usuwając wiodącąHTTP_
część. Czy jest to możliwe dzięki funkcjom lambda? (Myślę, że nazywają się funkcjami lambda) Pytam o to, ponieważ prawdopodobnie zrobiłbym to długo, najpierw iterując po nich, a następnie sprawdzając, czy zaczyna się od a,HTTP_
a następnie dodając go do nowego słownika. Dzięki jeszcze raz.lstrip('HTTP_')
zamiast wyrażenia regularnego. :)lstrip
tak naprawdę nie zrobi tego, o co go prosisz.lstrip
usunie wszystkie początkowe znaki, które pasują do dowolnych znaków w ciągu, który mu podasz, więc jeśli masz nagłówek"HTTP_TOKEN_ID"
, zwróci"OKEN_ID"
, ponieważ"T"
na początku"TOKEN"
dopasowania znak w ciągu przekazany do lstrip. Sposób na to jestprefix = 'HTTP_'; header = header[len(prefix):]
.HttpRequest.headers
.Począwszy od Django 2.2, możesz użyć,
request.headers
aby uzyskać dostęp do nagłówków HTTP. Z dokumentacji na HttpRequest.headers :Aby uzyskać wszystkie nagłówki, możesz użyć
request.headers.keys()
lubrequest.headers.items()
.źródło
Jest to inny sposób na zrobienie tego, bardzo podobny do powyższej odpowiedzi Manoj Govindana :
Spowoduje to również pobranie nagłówków
CONTENT_TYPE
iCONTENT_LENGTH
żądań wraz z innymiHTTP_
.request_headers['some_key]
==request.META['some_key']
.Zmodyfikuj odpowiednio, jeśli chcesz dołączyć / pominąć niektóre nagłówki. Django wymienia kilka z nich, ale nie wszystkie, tutaj: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
Algorytm Django dla nagłówków żądań:
-
podkreśleniem_
HTTP_
do wszystkich nagłówków w pierwotnym żądaniu, z wyjątkiemCONTENT_TYPE
iCONTENT_LENGTH
.Wartości każdego nagłówka nie powinny być modyfikowane.
źródło
re.compile(r'^(HTTP_.+|CONTENT_TYPE|CONTENT_LENGTH)$')
request.META.get („HTTP_AUTHORIZATION”)
/python3.6/site-packages/rest_framework/authentication.py
możesz to jednak uzyskać z tego pliku ...
źródło
Nie sądzę, aby istniał łatwy sposób na uzyskanie tylko nagłówków HTTP. Musisz iterować poprzez request.META dyktuje, aby uzyskać wszystko, czego potrzebujesz.
django-debug-toolbar stosuje to samo podejście do wyświetlania informacji w nagłówku. Spójrz na ten plik odpowiedzialny za pobieranie informacji z nagłówka.
źródło
Jeśli chcesz uzyskać klucz klienta z nagłówka żądania, możesz spróbować wykonać następujące czynności:
źródło
Wydaje się, że Twoim zamiarem jest użycie przychodzącego żądania HTTP do utworzenia kolejnego żądania HTTP. Coś jak brama. Istnieje doskonały moduł django-revproxy, który dokładnie to robi .
Źródło jest całkiem dobrym źródłem informacji o tym, jak osiągnąć to, co próbujesz zrobić.
źródło
źródło
Po prostu możesz użyć HttpRequest.headers od Django 2.2 i nowszych . Poniższy przykład pochodzi bezpośrednio z oficjalnej dokumentacji Django w sekcji Obiekty zapytań i odpowiedzi .
źródło