Django(十三)狀態保持 —— cookie與session+ajax異步請求+session記住登錄狀態+cookie記住登錄名密碼


一.狀態保持的概述

http協議是無狀態的。下一次去訪問一個頁面時並不知道上一次對這個頁面做了什么。因此引入了cookie、session兩種方式來配合解決此問題。
Duplicate entry:重復條目

二、Cookie(存儲在客戶端)

  • cookie是由服務器生成,存儲在瀏覽器端的一小段文本信息。
    在這里插入圖片描述

1.1 cookie的特點:

  1. 服務器通過HttpRessponse的對象set_cookie設置cookie:HttpRessponse.set_cookie
  2. 瀏覽器以鍵值對方式進行存儲。
  3. 通過瀏覽器訪問一個網站時,會將瀏覽器存儲的跟網站相關的所有cookie信息發送給該網站的服務器。(服務器取cookies:request.COOKIES
  4. cookie是基於域名安全的。www.baidu.com www.tudou.com
  5. cookie是有過期時間的,如果不指定,默認關閉瀏覽器之后cookie就會過期。

1.2 cookie基礎使用案例

1)app1/views.py編寫設置cookie設置/獲取函數

1.設置cookie:/setCookie
2.獲取cookie:/getCookie

#1.設置cookie:/setCookie
def set_cookie(request):
    '''請求設置cookie'''
    response=HttpResponse('設置cookie') #【1】
    response.set_cookie('name','jim')#【2】
    return response

#2.獲取cookie:/getCookie
def get_cookie(request):
    '''服務器獲取瀏覽器的cookie'''
    name=request.COOKIES['name']#【3】注意必須大寫
    return HttpResponse(name)

2)配置app1/urls.py

設置cookie頁
獲取cookie頁

from django.urls import path,re_path
from . import views

re_path('^setCookie$',views.set_cookie),#設置cookie頁
re_path('^getCookie$',views.get_cookie),#獲取cookie頁

效果:

http://127.0.0.1:8000/setCookie

顯示:設置cookie
在這里插入圖片描述
返回頭將看到:set-Cookie:name=jim; path=/
在這里插入圖片描述

http://127.0.0.1:8000/getCookie

顯示jim,請求頭里有個信息即發送給服務器的cookieCookie:sessionid=5pvq8zmkgtb9omarod4q52lhfsmcc5sp; csrftoken=hW4qfF5faVmg60G1RRf7KCL8ZuwnA0OR7OqYpufJedQOGY3IZKaZmS6EXbLfbk8j; name=jim
在這里插入圖片描述

關閉瀏覽器之后,再請求cookie即找不到之前設置的cookie,因為沒指定時間,所以用默認設置,關閉即過期:

http://127.0.0.1:8000/getCookie
在這里插入圖片描述

3)設置cookie過期時間views.py

  1. 設置過期方式一 【max_age】(單位:秒):max_age=14*24*3600 14天后過期
  2. 設置過期方式二 【expires】 (單位:時間):expires=datetime.now()+timedelta(days=14) 14天后過期
from django.shortcuts import render,redirect
from django.http import HttpResponse,JsonResponse
from datetime import datetime,timedelta #【0】注意引入

# /set_cookie
def set_cookie(request):
    '''設置cookie信息'''
    response = HttpResponse('設置cookie')
    # 設置一個cookie信息,名字為num, 值為1
    # response.set_cookie('num2', 2)
    response.set_cookie('num', 1, max_age=14*24*3600) #【1】14天后過期,單位,秒
    # response.set_cookie('num', 1, expires=datetime.now()+timedelta(days=14)) #【2】即現在時間為准+14天后過期
    # 返回response
    return response

效果:http://127.0.0.1:8000/setCookie

再設置時會看到一個14天的日期
在這里插入圖片描述
以后14天內這個cookie都會存在 。

4) 設置多個cookie

#1.設置cookie:/setCookie
def set_cookie(request):
    '''請求設置cookie'''
    
    response=HttpResponse('設置cookie')
    response.set_cookie('name','jim',max_age=14*24*3600) #14天后過期
    
    response=HttpResponse('設置cookie2')
    response.set_cookie('age',20,max_age=15*24*3600) #14天后過期
    return response

1.3 記住用戶名案例

1)templates/app1/login.html

【1】添加記住用戶名,設置cookie用,如果勾選則其value=on
【2】js添加是否記住用戶名
【3】js添加發送數據,加上remember
【4】把views頁的login()函數傳過來的用戶名,密碼賦值給對應處
用戶名:<input type="text" id="username" value="{{username}}"><br/>
密碼:<input type="password" id="password" value="{{password}}"><br/>

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <!-- 【0】引入jquery -->
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    <title>登錄頁面</title>
</head>
<script>
    // 寫ajax處理函數
    $(function () {
        $('#btnLogin').click(function () {
            //1.獲取用戶名、密碼、是否記住用戶名
            username=$('#username').val()
            password=$('#password').val()
            remember=$('#remember').val() //【2】是否記住用戶名
            //2.發起ajax--post(username,password)請求驗證,地址:/login_check
            $.ajax({
                'url':'/login_check',//驗證地址
                'type':'post',//請求類型
                'data':{'username':username,'password':password,'remember':remember},//【3】發送數據,加上remember
                'dataType':'json',//希望返回數據類型
            }).success(function(data){
                //成功返回{'res':1},失敗{'res':0}
                if(data.res===0){
                    $('#msg').show().html('用戶名或密碼錯誤請重試!')//登錄失敗則顯示msg,並在里寫入信息
                }else{//成功跳轉到books頁面
                    location.href='/books'
                }
            })

        })
    })
</script>
<style>
    /* 信息提示樣式 */
#msg{
    display: none;
    color:red;
}
</style>
<body>
    <!-- 原form刪除,input的name變id,方便jquery操作 -->
    <!-- 【4】把views頁的login()函數傳過來的用戶名,密碼賦值給對應處 -->
    用戶名:<input type="text" id="username" value="{{username}}"><br/>
    密碼:<input type="password" id="password" value="{{password}}"><br/>
    <!-- 加入一個信息提示框,用於密碼等錯誤提示 -->
    <div id="msg"></div>
    <!-- 【1】記住用戶名,設置cookie用,如果勾選則其value=on -->
    <input type="checkbox" id="remember">記住用戶名<br/>
    <!-- 按鈕type改button,加一個id方便jquery操作 -->
    <input type="button" id="btnLogin" value="登錄">

</body>
</html>

2)app1/urls.py(不重要)

【1】登錄頁
【2】登錄檢測

from django.urls import path,re_path
from . import views

urlpatterns=[
    path('login/',views.login),#【1】登錄頁
    path('login_check',views.login_check),#【2】登錄檢測

    re_path('^setCookie$',views.set_cookie),#設置cookie頁
    re_path('^getCookie$',views.get_cookie),#獲取cookie頁

    path('app1/',views.index),
    path('books/',views.books),

    # 書詳情頁,通過url接收參數2種寫法以下兩種都可:
    # path(r"detail/<int:bookId>",views.detail), #參數用尖括號包起來<>
    re_path(r"^detail/(\d+)",views.detail), #參數必須要帶括號

    path('addInfo/',views.addInfo), #添加三國書

    path(r'delete/<int:bid>',views.deleteInfo), #刪除對應圖書

    path(r'areas/',views.areas), #展示對應省市區信息

    path(r'test_ajax',views.test_ajax),#ajax測試頁
    path(r'ajax_handle/',views.ajax_handle),#ajax測試頁

    # re_path(r'^login_ajax', views.login_ajax), # 顯示ajax登錄頁面
    # re_path(r'^login_ajax_check', views.login_ajax_check), # ajax登錄校驗
]

3)app1/views.py【重點】

【1】接收remeber
【2】正確返回1,重寫
【3】如果remember==on,則把用戶名,密碼設置cookie到cookie
【4】不要忘記返回response
【5】如果用戶名密碼已經在cookie中,則取到它,並做為參數返回給渲染頁面
[6]獲取cookie中的用戶名、密碼

from django.shortcuts import render,redirect #引入重定向簡寫模塊
from app1.models import BookInfo,AreaInfo #從模型下導入bookinfo數據模型
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse #引入返回請求模塊、重新定向模塊
from datetime import datetime,timedelta # 引用時間模塊

def login(request):
    '''登錄頁'''
    #【5】如果用戶名密碼已經在cookie中,則取到它,並做為參數返回給渲染頁面
    if 'username' in request.COOKIES:
        #[6]獲取cookie中的用戶名、密碼
        username=request.COOKIES['username']
        password=request.COOKIES['password']
    else:
        username=''
        password=''
    return render(request,'app1/login.html',{'username':username,'password':password})

def login_check(request):
    '''登錄校驗'''
    #1.獲取用戶名密碼
    username=request.POST.get('username')
    password=request.POST.get('password')
    remember=request.POST.get('remember') #【1】接收remeber
    #2.進行校驗,並返回json數據
    if username=='jim' and password=='123':
        #return redirect('/books')
        response = JsonResponse({'res':1}) #【2】正確返回1,重寫
        #【3】如果remember==on,則把用戶名,密碼設置cookie到cookie
        if remember=='on':
            response.set_cookie('username',username,max_age=7*24*3600)
            response.set_cookie('password',password,max_age=7*24*3600)
        return response #【4】不要忘記返回response
    else:
        #return redirect('/login')
        return JsonResponse({'res':0}) #錯誤返回0

效果 http://127.0.0.1:8000/login/

如果勾選上記住用戶名,提交時會讓/login_check處理,把用戶名、密碼的cookie設置到瀏覽器,
再次來到login頁面時,用戶名密碼會通過templates/login頁里的變量直接賦值到對應處,從而實現免填密碼登錄。
在這里插入圖片描述

三、Session(存儲在服務器端)

session存儲在服務器端。
在這里插入圖片描述

1 配置

啟用Session

Django項目默認啟用Session。
打開test3/settings.py文件,在項MIDDLEWARE_CLASSES中啟用Session中間件。
session中間件
在這里插入圖片描述
禁用Session:將Session中間件刪除。
在這里插入圖片描述

存儲方式

打開test3/settings.py文件,設置SESSION_ENGINE項指定Session數據存儲的方式,可以存儲在數據庫、緩存、Redis等。

1)存儲在數據庫中,如下設置可以寫,也可以不寫,這是默認存儲方式。

SESSION_ENGINE='django.contrib.sessions.backends.db'
2)存儲在緩存中:存儲在本機內存中,如果丟失則不能找回,比數據庫的方式讀寫更快。

SESSION_ENGINE='django.contrib.sessions.backends.cache'
3)混合存儲:優先從本機內存中存取,如果沒有則從數據庫中存取。

SESSION_ENGINE='django.contrib.sessions.backends.cached_db'
4)如果存儲在數據庫中,需要在項INSTALLED_APPS中安裝Session應用。
在這里插入圖片描述
5)遷移后會在數據庫中創建出存儲Session的表。
在這里插入圖片描述
存儲session

6)表結構如下圖。
在這里插入圖片描述
存儲session表結構
由表結構可知,操作Session包括三個數據:鍵,值,過期時間。

2 使用方法:

1.設置:session:request.session['username']='jim'

2.獲取:session:request.session['username']

3.清除所有session,在存儲中刪除值部分。

request.session.clear()

4. 清除session數據,在存儲中刪除session的整條數據。

request.session.flush()

5. 刪除session中的指定鍵及值,在存儲中只刪除某個鍵及對應的值。

del request.session['鍵']

6.設置會話的超時時間,如果沒有指定過期時間則兩個星期后過期。

request.session.set_expiry(value)

  • 如果value是一個整數,會話將在value秒沒有活動后過期。
  • 如果value為0,那么用戶會話的Cookie將在用戶的瀏覽器關閉時過期。
  • 如果value為None,那么會話永不過期。

3.1 session的特點:

  1. session是以鍵值對進行存儲的。
  2. session依賴於cookie。唯一的標識碼保存在sessionid cookie中。
  3. session也是有過期時間,如果不指定,默認兩周就會過期。
  1. 保存的是字符串,得到就是字符串,是數字,得到即數字。
  2. session保存位置:對應數據庫的表 django_session
  3. 在這里插入圖片描述
  4. 在這里插入圖片描述

3.2 session基本設置、獲取、清除案例

1)app1/views.py

設置session過期時間

#test /set_session
def set_session(request):
    '''設置session'''
    request.session['username'] = 'smart'
    request.session['age'] = 18
    # request.session.set_expiry(5) #設置session過期時間
    return HttpResponse('設置session')


#test /get_session
def get_session(request):
    '''獲取session'''
    username = request.session['username']
    age = request.session['age']
    return HttpResponse(username+':'+str(age))


#test /clear_session
def clear_session(request):
    '''清除session信息'''
    # request.session.clear()
    request.session.flush()
    return HttpResponse('清除成功')

2)app1/urls.py

	re_path('^setSession$',views.set_session),#設置session頁
    re_path('^getSession$',views.get_session),#獲取session頁
    re_path('^clearSession$',views.clear_session),#獲取session頁

效果 http://127.0.0.1:8000/setSession

在這里插入圖片描述

http://127.0.0.1:8000/getSession

在這里插入圖片描述

http://127.0.0.1:8000/clearSession

在這里插入圖片描述

擴展:session的數據庫保存值是base64編碼

可在百度搜索 【base64解碼】,查看其保存具體信息
在這里插入圖片描述
https://base64.supfree.net/
在這里插入圖片描述

3.3 記住用戶登錄狀態案例

1)app1/views.py編寫登錄函數:設置session,讀取session

【1】如果用戶勾選了remember的條件下,設置session,記住用戶登錄狀態
【2】判斷用戶是否登錄,用戶已登錄, 直接跳轉到圖書列表

from django.shortcuts import render,redirect #引入重定向簡寫模塊
from app1.models import BookInfo,AreaInfo #從模型下導入bookinfo數據模型
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse #引入返回請求模塊、重新定向模塊
from datetime import datetime,timedelta # 引用時間模塊

def login(request):
    '''登錄頁'''
    # 【2】判斷用戶是否登錄,用戶已登錄, 直接跳轉到圖書列表
    if request.session.has_key('islogin'):
        return redirect('/books')
    else:
        #如果用戶名密碼已經在cookie中,則取到它,並做為參數返回給渲染頁面
        if 'username' in request.COOKIES:
            #獲取cookie中的用戶名、密碼
            username=request.COOKIES['username']
            password=request.COOKIES['password']
        else:
            username=''
            password=''
    return render(request,'app1/login.html',{'username':username,'password':password})

def login_check(request):
    '''登錄校驗'''
    #1.獲取用戶名密碼
    username=request.POST.get('username')
    password=request.POST.get('password')
    remember=request.POST.get('remember') #接收remeber
    #2.進行校驗,並返回json數據
    if username=='jim' and password=='123':
        #return redirect('/books')
        response = JsonResponse({'res':1}) #正確返回1,重寫
        #如果remember==on,則把用戶名,密碼設置cookie到cookie
        if remember=='on':
            response.set_cookie('username',username,max_age=7*24*3600)
            response.set_cookie('password',password,max_age=7*24*3600)

        # 【1】如果用戶勾選了remember的條件下,設置session,記住用戶登錄狀態
        request.session['islogin'] = True # 只有session中有islogin,就認為用戶已登錄
        return response #不要忘記返回response
    else:
        #return redirect('/login')
        return JsonResponse({'res':0}) #錯誤返回0

2)app1/urls.py

from django.urls import path,re_path
from . import views

urlpatterns=[
    path('login/',views.login),#登錄頁
    path('login_check',views.login_check),#登錄檢測
    ]

3)templates/app1/login.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <!-- 【0】引入jquery -->
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    <title>登錄頁面</title>
</head>
<script>
    // 寫ajax處理函數
    $(function () {
        $('#btnLogin').click(function () {
            //1.獲取用戶名、密碼、是否記住用戶名
            username=$('#username').val()
            password=$('#password').val()
            remember=$('#remember').val() //【2】是否記住用戶名
            //2.發起ajax--post(username,password)請求驗證,地址:/login_check
            $.ajax({
                'url':'/login_check',//驗證地址
                'type':'post',//請求類型
                'data':{'username':username,'password':password,'remember':remember},//【3】發送數據,加上remember
                'dataType':'json',//希望返回數據類型
            }).success(function(data){
                //成功返回{'res':1},失敗{'res':0}
                if(data.res===0){
                    $('#msg').show().html('用戶名或密碼錯誤請重試!')//登錄失敗則顯示msg,並在里寫入信息
                }else{//成功跳轉到books頁面
                    location.href='/books'
                }
            })

        })
    })
</script>
<style>
    /* 信息提示樣式 */
#msg{
    display: none;
    color:red;
}
</style>
<body>
    <!-- 原form刪除,input的name變id,方便jquery操作 -->
    <!-- 【4】把views頁的login()函數傳過來的用戶名,密碼賦值給對應處 -->
    用戶名:<input type="text" id="username" value="{{username}}"><br/>
    密碼:<input type="password" id="password" value="{{password}}"><br/>
    <!-- 加入一個信息提示框,用於密碼等錯誤提示 -->
    <div id="msg"></div>
    <!-- 【1】記住用戶名,設置cookie用,如果勾選則其value=on -->
    <input type="checkbox" id="remember">記住用戶名<br/>
    <!-- 按鈕type改button,加一個id方便jquery操作 -->
    <input type="button" id="btnLogin" value="登錄">

</body>
</html>

效果:http://127.0.0.1:8000/login

  1. 第一次登錄勾選記住用戶名密碼后
  2. 再訪問登錄頁時,將自動跳轉到:http://127.0.0.1:8000/books

3.4 cookie和session的應用場景

  • cookie:記住用戶名。安全性要求不高。
  • session:涉及到安全性要求比較高的數據。銀行卡賬戶,密碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM