मुझे Django में सभी अनुरोध हेडर कैसे मिल सकते हैं?


107

मुझे सभी Django अनुरोध हेडर प्राप्त करने की आवश्यकता है। जो मैंने पढ़ा है, उससे Django बस request.METAएक बहुत कुछ अन्य डेटा के साथ चर में सब कुछ डंप करता है। सभी शीर्षकों को प्राप्त करने का सबसे अच्छा तरीका क्या होगा जो क्लाइंट ने मेरे Django एप्लिकेशन को भेजा है?

मैं httplibअनुरोध का निर्माण करने के लिए इनका उपयोग कर रहा हूं ।

जवाबों:


139

प्रलेखन के अनुसार request.METAएक "मानक पायथन शब्दकोश है जिसमें सभी उपलब्ध HTTP हेडर हैं"। यदि आप सभी शीर्षकों को प्राप्त करना चाहते हैं, तो आप केवल शब्दकोश के माध्यम से पुनरावृति कर सकते हैं।

ऐसा करने के लिए आपके कोड का कौन सा भाग आपकी सटीक आवश्यकता पर निर्भर करता है। कहीं भी पहुंचना requestचाहिए।

अपडेट करें

मुझे इसे मिडिलवेयर क्लास में एक्सेस करने की आवश्यकता है लेकिन जब मैं इस पर पुनरावृति करता हूं, तो मुझे HTTP हेडर के अलावा बहुत सारे मान मिलते हैं।

प्रलेखन से:

के अपवाद के साथ CONTENT_LENGTHऔर CONTENT_TYPE, जैसा कि ऊपर दिया गया है, HTTPअनुरोध में किसी भी हेडर को METAसभी वर्णों को अपरकेस में परिवर्तित करके, किसी भी हाइफ़न को अंडरस्कोर के साथ बदलकर और उपसर्ग को नाम में जोड़ दिया जाता हैHTTP_

(महत्व दिया)

HTTPहेडर को अकेले लाने के लिए , केवल उपसर्गों के आधार पर फ़िल्टर करें HTTP_

अपडेट २

क्या आप मुझे दिखा सकते हैं कि मैं अनुरोध से सभी कुंजी को फ़िल्टर करके हेडर का एक शब्दकोश कैसे बना सकता हूं। एमटीए चर जो एक HTTP_ भाग से शुरू होता है और प्रमुख HTTP_ भाग को बाहर निकालता है।

ज़रूर। यहाँ यह करने का एक तरीका है।

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

मुझे इसे मिडलवेयर क्लास में एक्सेस करने की आवश्यकता है लेकिन जब मैं इस पर पुनरावृति करता हूं, तो मुझे HTTP हेडर के अलावा बहुत सारे मान मिलते हैं।
मृदंग अग्रवाल

धन्यवाद मनोज जिज्ञासा से बाहर - क्या आप मुझे दिखा सकते हैं कि कैसे मैं हेडर के एक शब्दकोश का निर्माण कर सकता हूं, request.METAचर से सभी कुंजी को फ़िल्टर करके जो कि एक HTTP_प्रमुख HTTP_भाग से शुरू होता है और बाहर निकलता है । क्या यह लैम्ब्डा कार्यों के माध्यम से संभव है? (मुझे लगता है कि उन्हें लंबोदर फंक्शंस कहा जाता है) मैं यह इसलिए पूछ रहा हूं क्योंकि मैं शायद पहले उन पर पुनरावृत्ति करके लंबा रास्ता तय करूंगा, फिर यह देखने के लिए जांच करूंगा कि क्या यह शुरू होता है HTTP_और फिर इसे नए शब्दकोश में जोड़ते हैं। एक बार फिर धन्यवाद।
मृदंग अग्रवाल

धन्यवाद फिर से मनोज। मैंने इसे lstrip('HTTP_')रेगेक्स के बजाय उपयोग करने के लिए थोड़ा संशोधित किया । :)
मृदंग अग्रवाल

3
@ मृदंग अग्रवाल: lstripवास्तव में वह नहीं करेंगे जो आप इसे करने के लिए कह रहे हैं। lstripआपके द्वारा दिए गए स्ट्रिंग में किसी भी वर्ण से मेल खाने वाले सभी प्रमुख वर्णों को अलग कर देगा, इसलिए यदि आपके पास कोई हेडर "HTTP_TOKEN_ID"है तो वह वापस दे देगा "OKEN_ID", क्योंकि स्ट्रिंग में एक वर्ण "T"से "TOKEN"मेल खाने की शुरुआत में वह लैस्ट्रिप के पास जाता है। इसे करने का तरीका है prefix = 'HTTP_'; header = header[len(prefix):]
jcdyer

2
Django 2.2 ने समर्थन किया है HttpRequest.headers
Dcalsky

30

Django 2.2 से शुरू, आप request.headersHTTP हेडर का उपयोग करने के लिए उपयोग कर सकते हैं । HttpRequest.headers पर प्रलेखन से :

एक असंवेदनशील, तानाशाह जैसी वस्तु जो अनुरोध से सभी HTTP-उपसर्ग हेडर (प्लस सामग्री-लंबाई और सामग्री-प्रकार) तक पहुंच प्रदान करती है।

प्रत्येक शीर्षलेख का नाम शीर्षक-आवरण (जैसे उपयोगकर्ता-एजेंट) के साथ प्रदर्शित किया जाता है जब इसे प्रदर्शित किया जाता है। आप हेडर केस को असंवेदनशील तरीके से एक्सेस कर सकते हैं:

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

यह ऐसा करने का एक और तरीका है, ऊपर मनोज गोविंदन के उत्तर के समान है :

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. UPPERCASE में कनवर्ट करें।
  3. HTTP_मूल अनुरोध में सभी शीर्षकों को छोड़ें , को छोड़कर CONTENT_TYPEऔर CONTENT_LENGTH

प्रत्येक हेडर के मान को अनमॉडिफाइड किया जाना चाहिए।


5
कि सभी को एक एकल regexp में जोड़ा जा सकता है,re.compile(r'^(HTTP_.+|CONTENT_TYPE|CONTENT_LENGTH)$')
Rebs


3

मुझे नहीं लगता कि केवल HTTP हेडर प्राप्त करने का कोई आसान तरीका है। आपको अनुरोध के माध्यम से पुनरावृत्त करना होगा। जो कुछ भी आप की आवश्यकता है उसे प्राप्त करने के लिए एमटीए को निर्धारित करें।

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

सीधे शब्दों में आप उपयोग कर सकते HttpRequest.headers से Django 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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.