zoukankan      html  css  js  c++  java
  • 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:涉及到安全性要求比较高的数据。银行卡账户,密码
  • 相关阅读:
    再谈C#装箱和拆箱操作
    C#装箱与拆箱总结
    大话设计模式
    创建ASP.NET Webservice
    Lambada和linq查询数据库的比较
    设置VS2015背景图片(转载)
    windows 下使用Linux 子系统-安装.net core 环境
    .net core 3.1 ef Migrations 使用 CLI 数据迁移及同步
    linq 大数据 sql 查询及分页优化
    数据迁移最快方式,多线程并行执行 Sql插入
  • 原文地址:https://www.cnblogs.com/chenxi188/p/12176700.html
Copyright © 2011-2022 走看看