2013-02-27 18 views
5


W Django (i ogólnie) jest ciasteczko również nagłówek, podobnie jak np. User-Agent?
To znaczy, czy te dwie metody są równoważne w Django?

Korzystanie set_cookie:
Django ciasteczka i nagłówki

response.set_cookie('food', 'bread') 
response.set_cookie('drink', 'water') 

Korzystanie ustawienie nagłówka:

response['Cookie'] = ('food=bread; drink=water') 
# I'm not sure whether 'Cookie' should be capitalized or not 


Ponadto, jeśli możemy ustawić ciasteczko za pomocą drugiego sposobu, w jaki możemy zawierać dodatkowe informacje,
lubię path, max_age itd. W ciągu znaków? Czy po prostu rozdzielimy je specjalnym znakiem
?

Odpowiedz

3

Byłoby znacznie łatwiej, jeśli używasz set_cookie. Ale tak, można ustawić ciasteczko przez ustawienie nagłówka odpowiedzi:

response['Set-Cookie'] = ('food=bread; drink=water; Path=/; max_age=10') 

Jednak od resetowania Set-Cookie w response obiektu będzie usunąć poprzednią jedną, nie może mieć więcej niż jeden Set-Cookie nagłówek w Django. Zobaczmy, dlaczego jest to .

przestrzegać w response.py, set_cookie method:

class HttpResponseBase: 

    def __init__(self, content_type=None, status=None, mimetype=None): 
     # _headers is a mapping of the lower-case name to the original case of 
     # the header (required for working with legacy systems) and the header 
     # value. Both the name of the header and its value are ASCII strings. 
     self._headers = {} 
     self._charset = settings.DEFAULT_CHARSET 
     self._closable_objects = [] 
     # This parameter is set by the handler. It's necessary to preserve the 
     # historical behavior of request_finished. 
     self._handler_class = None 
     if mimetype: 
      warnings.warn("Using mimetype keyword argument is deprecated, use" 
          " content_type instead", 
          DeprecationWarning, stacklevel=2) 
      content_type = mimetype 
     if not content_type: 
      content_type = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE, 
        self._charset) 
     self.cookies = SimpleCookie() 
     if status: 
      self.status_code = status 

     self['Content-Type'] = content_type 

    ... 

    def set_cookie(self, key, value='', max_age=None, expires=None, path='/', 
        domain=None, secure=False, httponly=False): 
     """ 
     Sets a cookie. 

     ``expires`` can be: 
     - a string in the correct format, 
     - a naive ``datetime.datetime`` object in UTC, 
     - an aware ``datetime.datetime`` object in any time zone. 
     If it is a ``datetime.datetime`` object then ``max_age`` will be calculated. 

     """ 
     self.cookies[key] = value 
     if expires is not None: 
      if isinstance(expires, datetime.datetime): 
       if timezone.is_aware(expires): 
        expires = timezone.make_naive(expires, timezone.utc) 
       delta = expires - expires.utcnow() 
       # Add one second so the date matches exactly (a fraction of 
       # time gets lost between converting to a timedelta and 
       # then the date string). 
       delta = delta + datetime.timedelta(seconds=1) 
       # Just set max_age - the max_age logic will set expires. 
       expires = None 
       max_age = max(0, delta.days * 86400 + delta.seconds) 
      else: 
       self.cookies[key]['expires'] = expires 
     if max_age is not None: 
      self.cookies[key]['max-age'] = max_age 
      # IE requires expires, so set it if hasn't been already. 
      if not expires: 
       self.cookies[key]['expires'] = cookie_date(time.time() + 
                  max_age) 
     if path is not None: 
      self.cookies[key]['path'] = path 
     if domain is not None: 
      self.cookies[key]['domain'] = domain 
     if secure: 
      self.cookies[key]['secure'] = True 
     if httponly: 
      self.cookies[key]['httponly'] = True 

dwie rzeczy warto zwrócić uwagę na:

  1. set_cookie sposób zadba o obsługę datetime w expires dla was, i będzie trzeba go ustawić siebie, czy sam to ustawisz.
  2. self.cookie to słownik dyktowanych. Więc każdy key doda ["Set-Cookie"] w nagłówku, jak wkrótce zobaczysz.

cookies obiekt wewnątrz HttpResponse następnie przejdzie do WSGIHandler i uzyskać załączonym do nagłówka odpowiedzi:

response_headers = [(str(k), str(v)) for k, v in response.items()] 
for c in response.cookies.values(): 
    response_headers.append((str('Set-Cookie'), str(c.output(header='')))) 

Powyższy kod jest również dlaczego tylko set_cookie() umożliwiają wielokrotne Set-Cookie w nagłówku odpowiedzi, i że ustawienie pliku cookie bezpośrednio na obiekcie Response zwróci tylko jedną wartość: Set-Cookie.

0

Jasne, ale zmiana „Cookie” na „Set-Cookie” i dodać „Path = /”, aby uczynić z niego miejsce szeroki.

response["Set-Cookie"] = "food=bread; drink=water; Path=/" 

Edit:

Po wypróbowaniu to uwagę sam znalazłem ciekawą dziwactwo, set_cookie nie grupować podobne ciasteczka (sama ścieżka, wygasa, domena itp) w taki sam cel. Dodaje tylko odpowiedź "Set-Cookie". Zrozumiałe, ponieważ sprawdzanie i komunikowanie się z ciągami zajęłoby prawdopodobnie więcej czasu niż posiadanie kilku dodatkowych bajtów w nagłówkach HTTP (i byłoby to w najlepszym razie optymalizacja mikro).

response.set_cookie("food", "kabanosy") 
response.set_cookie("drink", "ardbeg") 
response.set_cookie("state", "awesome") 

# result in these headers 
# Set-Cookie: food=kabonosy; Path=/ 
# Set-Cookie: drink=ardbeg; Path=/ 
# Set-Cookie: state=awesome; Path=/ 

# not this 
# Set-Cookie:food=kabanosy; drink=ardbeg; state=awesome; Path=/ 
+0

A więc, jeśli mam ustawić dwa różne pliki cookie, o różnych parametrach 'ścieżka' i' max_age'; ale używając składni 'response [" Set-Cookie "] = ...' –

+0

Szczerze mówiąc, lepiej używać 'set_cookie', ponieważ nie ma prawdziwej korzyści z samodzielnego ustawiania nagłówków. Byłoby jednak coś takiego: 'odpowiedź [" Set-Cookie "] =" food = kabanosy; Max-Age = 86400; Path =/"'. – Matt

+0

Wiem, że w zasadzie wygodniej jest używać 'set_cookie', ale chciałbym zrozumieć jego związek z obiektem' HttpResponse' iz nagłówkami. –

1

fragment z kodem HttpResponse klasa:

class HttpResponse(object): 

    #... 

    def __init__(self, content='', mimetype=None, status=None, 

     #... 

     self.cookies = SimpleCookie() 

    #... 

    def set_cookie(self, key, value='', max_age=None, expires=None, path='/', 
        domain=None, secure=False, httponly=False): 

     self.cookies[key] = value 

     #... 


Oznacza to, że ilekroć response.set_cookie() nazywa, to albo umieszcza nowy plik cookie
value na response.cookies[key] lub zmienia istniejące wartość, jeśli jest taka przy tym kluczu.
Wyjaśnia, dlaczego ustawia wiele nagłówków Set-Cookie.
Zastanawiam się, jak moglibyśmy zrobić to samo z response['Set-Cookie'].

Powiązane problemy