狀態(tài)保持
- 瀏覽器請求服務(wù)器是無狀態(tài)無記憶的冗栗。
- 無狀態(tài)無記憶原因:瀏覽器與服務(wù)器是使用Socket進行通信的王污,服務(wù)器將請求結(jié)果返回給瀏覽器,會關(guān)閉當(dāng)前的Socket連接棒妨,而且服務(wù)器也會處理頁面完畢之后銷毀頁面對象。
- 有時需要保持用戶瀏覽的狀態(tài)含长,所有我們要實現(xiàn)狀態(tài)保持券腔。
- 在客戶端存儲信息使用cookie
- 在服務(wù)器存儲信息使用session
Cookie 是保持在客戶端,基于域名(Domain)的
- 設(shè)置Cookie
def set_cookie(request):
username = request.GET.get('username')
response = HttpResponse('set_cookie')
# 通過HttpResponse對象的set_cookie方法來設(shè)置cookie
# max_age單位為秒拘泞, 默認(rèn)是None 如果是臨時cookie,可不設(shè)置
response.set_cookie('username', username, max_age=3600)
return response
- 讀取Cookie
def get_cookie(request):
cookie = request.COOKIES
username = cookie.get('username')
return HttpResponse('get_cookie:', username)
3.Cookie的請求流程
- 第一次請求過程
① 我們的瀏覽器第一次請求服務(wù)器的時候,不會攜帶任何cookie信息
② 服務(wù)器接收到請求之后,發(fā)現(xiàn) 請求中沒有任何cookie信息
③ 服務(wù)器設(shè)置一個cookie.這個cookie設(shè)置在響應(yīng)中
④ 我們的瀏覽器接收到這個響應(yīng)之后,發(fā)現(xiàn)響應(yīng)中有cookie信息,瀏覽器會將cookie信息保存起來 - 第二次以及以后請求過程
⑤ 當(dāng)我們的瀏覽器第二次及其之后的請求都會攜帶cookie信息
⑥ 我們的服務(wù)器接收到請求之后,會發(fā)現(xiàn)請求中攜帶的cookie信息,這樣的話就認(rèn)識是誰的請求了
4.從HTTP協(xié)議角度深度掌握Cookie流程
- 第一次
① 我們是第一次請求服務(wù)器,不會攜帶任何cookie信息,請求頭中沒有任何cookie信息
② 服務(wù)器會為響應(yīng)設(shè)置cookie信息. 響應(yīng)頭中有set_cookie信息 - 第二次及其之后的
③ 我們第二次及其之后的請求都會攜帶cookie信息,請求頭中有cookie信息
④ 在當(dāng)前我們的代碼中,沒有在響應(yīng)頭中設(shè)置cookie,所以響應(yīng)頭中沒有set_cookie信息
Session是保存在服務(wù)器 依賴于Cookie,禁用Cookie則Session無法實現(xiàn)
1.啟用Session
Django項目默認(rèn)啟用Session纷纫。
image.png
2.存儲方式
- 存儲在數(shù)據(jù)庫中,如下設(shè)置可以寫陪腌,也可以不寫辱魁,這是默認(rèn)存儲方式。
SESSION_ENGINE='django.contrib.sessions.backends.db'
# 如果存儲在數(shù)據(jù)庫中诗鸭,需要在項INSTALLED_APPS中安裝Session應(yīng)用染簇。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions', # 安裝Session應(yīng)用
'django.contrib.messages',
'django.contrib.staticfiles',
'book.apps.BookConfig',
]
- 本地緩存 存儲在本機內(nèi)存中,如果丟失則不能找回强岸,比數(shù)據(jù)庫的方式讀寫更快锻弓。
SESSION_ENGINE='django.contrib.sessions.backends.cache'
- 混合存儲 優(yōu)先從本機內(nèi)存中存取,如果沒有則從數(shù)據(jù)庫中存取蝌箍。
SESSION_ENGINE='django.contrib.sessions.backends.cached_db
- 在redis中保存session青灼,需要引入第三方擴展,我們可以使用django-redis來解決妓盲。
1) 安裝擴展
pip install django-redis
2)配置
在settings.py文件中做如下設(shè)置
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
3.設(shè)置Session
def set_session(request):
# 1.cookie中沒有任何信息
print(request.COOKIES)
#2.對用戶名和密碼進行驗證
# 假設(shè)認(rèn)為 用戶名和密碼正確
user_id=6666
#3.設(shè)置session信息
# 設(shè)置session的時候其實 session做了2件事
#第一件: 將數(shù)據(jù)保存在數(shù)據(jù)庫中
#第二件: 設(shè)置一個cookie信息杂拨,這個cookie信息是以sessionid為key
request.session['user_id']=user_id
#4. 返回響應(yīng)
return HttpResponse('set_session')
4.讀取Session信息
def get_session(request):
# . 請求都會攜帶 session id信息
print(request.COOKIES)
# 2. 會獲取到sessionid信息,然后進行驗證,
# 驗證成功,可以獲取 session信息(
# request.session 字典
user_id=request.session['user_id']
user_id=request.session.get('user_id')
# 3.返回響應(yīng)
return HttpResponse('get_session')
5.Session流程
- 第一次請求:
① 我們第一次請求的時候可以攜帶一些信息(用戶名/密碼) cookie中沒有任何信息
② 當(dāng)我們的服務(wù)器接收到這個請求之后,進行用戶名和密碼的驗證,驗證沒有問題可以設(shè)置session 信息
③ 在設(shè)置session信息的同時(session信息保存在服務(wù)器端).服務(wù)器會在響應(yīng)頭中設(shè)置一個 sessionid 的cookie信息
④ 客戶端(瀏覽器)在接收到響應(yīng)之后,會將cookie信息保存起來(保存 sessionid的信息) - 第二次及其之后的請求:
⑤ 第二次及其之后的請求都會攜帶 session id信息
⑥ 當(dāng)服務(wù)器接收到這個請求之后,會獲取到sessionid信息,然后進行驗證,
驗證成功,則可以獲取 session信息(session信息保存在服務(wù)器端)
6.HTTP協(xié)議角度深度掌握Session流程
① 第一次請求,在請求頭中沒有攜帶任何cookie信息
② 我們在設(shè)置session的時候,session會做2件事.
#第一件: 將數(shù)據(jù)保存在數(shù)據(jù)庫中
#第二件: 設(shè)置一個cookie信息,這個cookie信息是以sessionid為key value為 xxxx
③ 第二次及其之后的:都會攜帶 cookie信息,特別是 sessionid