• Django跨域、cookie、session


    前后台分离开发

    1.前台页面运行在前台服务器上,负责页面的渲染(静态文件的加载)与跳转

    2.后台代码运行在后台服务器上,负责数据的处理(提供数据请求的接口)

    跨域

    什么是跨域?

    通常情况下,A网页访问B服务器时,不满足以下三个条件中,其中之一就是跨域访问:

    1.协议不同;

    2.端口不同;

    3.主机不同

    如何解决?

    #安装django-cors-headers模块
    
    #在settings.py中配置
    #注册app
    INSTALLED_APPS = [
        'corsheaders'
    ]
    
    #添加中间件
    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware'   
    ]
    
    #允许跨域源
    CORS_ORIGIN_ALLOW_ALL = True
    '''
    前台代码
    $.ajax({
        url: 'http://127.0.0.1:8731/login/',
        type: 'post',
        data: {
            usr: 'abc',
            pwd: '123'
        },
        success: function (data) {
            console.log(data);
            // 可以完成页面的局部刷新
        }
    })
    
    后台代码
    def login(request):
        # 假设数据库存放的用户信息为 abc:123
        if request.method == 'POST':
            usr = request.POST.get('usr', None)
            pwd = request.POST.get('pwd', None)
            if usr == 'abc' and pwd == '123':
                return JsonResponse({'status': 'OK', 'usr': usr})
        return JsonResponse({'status': 'error', 'usr': None})
    '''
    代码

    文件上传

    浏览器:

    <form>
        <input class="file" type="file">
        <button type="button" class="upload">上传</button>
    </form>
    <script>
        $('.upload').click(function () {
            var form_data = new FormData();
            var file = $('.file')[0].files[0];
            form_data.append('file', file);
            $.ajax({
                url: '跨域上传地址',
                type: 'post',
                data: form_data,
                contentType: false,  // 不设置内容类型
                processData: false,  // 不预处理数据
                success: function (data) {
                    console.log(data)
                }
            })
        })
    </script>

    后台:

    def upload(request):
        file = request.FILES.get('file', None)
        if file:
            with open(file.name, 'wb') as f:
                for line in file:
                    f.write(line)
        return JsonResponse({
            'status': 'OK',
            'msg': 'upload success'
        })

    文件下载

    浏览器:

    <a href="http://127.0.0.1:8121/download/">下载</a>
    <button type="button" class="download">下载</button>
    <script>
        $('.download').click(function () {
            location.href = 'http://127.0.0.1:8121/download/'
        })
    </script>

    后台:

    def download(request):
        file = open('123.zip', 'rb')
        response = FileResponse(file)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="%s"' % file.name
        return response

    Cookie

    1.什么是cookie?

    cookie指的是前端浏览器以明文的形式存放具有key、value信息特征的字符串。

    2.cookie的作用

    在前后台均可以访问并设置cookie,从而解决http协议的无状态特点所导致的前后两次请求无逻辑可循的问题(例如:不同用户登录后,再进入个人主页,明显是有信息区别的)

    3.cookie简介

    随着浏览器的发展,很多浏览器不再对cookie的个数加以限制,但是仍存在大小的限制,一般为4k;但是为了达到传输的高效,服务器的解析速度,还是建议开发者严格控制cookie的个数。

    cookie初始:为页面文档document的一个字符串属性:document.cookie = 'key=value;'

    Cookie的使用及其参数:

    #Django用HttpResponse对象操作Cookie
    response = HttpResponse('所有的响应都是HttpResponse对象')
    
    #设置cookie:key,value与过期时间(max_age)
    response.set_cookie(key,value,max_age)
    
    #删除cookie:key
    response.delete_cookie(key)
    
    #设置加盐cookie:key,value与盐字符串(就是简易的加密)
    response.set_signed_cookie(key,value,salt)
    
    #通过request对象获取cookie
    # 获取key对应的value
    request.COOKIES.get(key, None)
    # 获取加盐后的key对应的value
    request.get_signed_cookie(key, salt)
    
    
    #set_cookie方法的其他参数
    1. expires:过期时间,格式为字符串类型的时间
    2. path:作用路径,/代表所有路径下均起作用
    3. domain:作用域名
    4. secure:布尔类型,浏览器是否通过HTTPS方式回传cookie
    5. httponly:布尔类型,JS能否直接访问该条cookie
    # views.py
    from django.shortcuts import render, redirect, HttpResponse
    
    # 确认登录装饰器
    def login_check(func):
        def inner(request, *args, **kwargs):
            is_login = request.COOKIES.get('is_login', False)
            # 确定当前被装饰的请求,登录完毕可以跳转回去
            url = request.get_full_path()
            if is_login:
                return func(request, *args, **kwargs)
            else:
                # 将回跳的路径作为参数(登录的表单action需要空着不写)
                return redirect('/login/?back_url=%s' % url)
        return inner
    
    # 主页
    def index(request):
        return render(request, 'index.html')
    
    # 登录页面
    def login(request):
        if request.method == "GET":
            return render(request, 'login.html')
        if request.method == "POST":
            # 获取回跳的地址
            back_url = request.GET.get('back_url', '/index/')
            usr = request.POST.get('usr', None)
            pwd = request.POST.get('pwd', None)
            if usr == 'abc' and pwd == '123':
                # 确定回跳
                response = redirect(back_url)
                # 登录成功获取cookie
                for i in range(500):
                    response.set_cookie('usr%i' % i, usr)
                response.set_cookie('is_login', True)
                return response
    
    @login_check
    def order(request):
        print(request.COOKIES)
        usr = request.COOKIES.get('usr', None)
        return render(request, 'order.html', locals())
    
    @login_check
    def user(request):
        usr = request.COOKIES.get('usr', None)
        return render(request, 'user.html', locals())
    
    def logout(request):
        response = HttpResponse('注销成功')
        response.delete_cookie('is_login')
        response.delete_cookie('usr')
        return response
    cookie实例
    index.html
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>主页</title>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
    </head>
    <body>
    <div class="container">
        <div class="row">
            <h1 class="page-header text-info text-center">主页</h1>
        </div>
        <div class="row">
            <a href="/login/" class="btn text-danger"><h3>登录</h3></a>
            <a href="/user/" class="btn text-info"><h3>个人主页</h3></a>
            <a href="/order/" class="btn text-info"><h3>订单详情</h3></a>
            <a href="/login_out/" class="btn text-info"><h3>注销</h3></a>
        </div>
    </div>
    
    </body>
    </html>
    
    login.html
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录</title>
    </head>
    <body>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录界面</title>
        <link rel="stylesheet" href="/static/login.css">
    </head>
    <body>
        <div class="box">
            <h2>欢迎登录</h2>
            <form action="" method="post">
                <div class="usr">
                    用 户:<input type="text" name="usr" placeholder="请输入用户名">
                </div>
                <div class="usr">
                    密 码:<input type="password" name="pwd" placeholder="请输入密码">
                </div>
                <div class="login">
                    <input type="submit" value="登录">
                </div>
            </form>
        </div>
    </body>
    </html>
    </body>
    </html>
    
    user.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>个人主页</title>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
    </head>
    <body>
    <h1 class="text-primary col-md-6 page-header text-center">{{ usr }}的个人主页</h1>
    </body>
    </html>
    
    order.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>订单详情</title>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css">
    </head>
    <body>
    <h1 class="page-header text-center text-primary col-md-6">{{ usr }}的订单详情</h1>
    </body>
    </html>
    模板层

    Session

    1.什么是session?

    session指的是在后台通常以密文的形式存放key,value形式的数据,一个会话存放为数据库的一条字段。

    2.session的作用

    必须结合cookie使用,解决了cookie的不安全性。

    3.session简介:session时存放在服务器端的key-value形式的状态数据。

    session使用及其参数:

    #常用操作:
    #设置
    request.session['key1'] = 'value1'
    request.session['key2'] = 'value2'
    #过程:
    #1.生成一个随机字符串,作为主键;
    #2.在django_session表中插入有三个字段的一条数据(一条数据对应一个浏览器会话)
    --session_key:主键-随机字符串
    --session_data:该会话拥有的所有key-value形成的大字典的加密字符串
    --expire_date:过期时间,默认14天
    #3.往浏览器中写入一条cookie,sessionid=主键的随机字符串
    
    #获取
    request.session.get('key',None)
    
    #删除
    request.session.delete()  #只删除当前会话对应的一条记录
    request.session.flush()  #除了删除当前会话对应的一条记录外,还删除对应浏览器中的cookie
    
    #其他
    request.session.session_key  # 获取当前会话对应的session_key
    request.session.exists('session_key')  # 判断某session_key是否存在
    request.session.clear_expired()  # 清空所有过期的Session

    settings.py中的配置:

    1. 数据库Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
    
    2. 缓存Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
    
    3. 文件Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 
    
    4. 缓存+数据库
    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
    
    5. 加密Cookie Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
    
    其他公用设置项:
    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
  • 相关阅读:
    Self referencing loop detected for property 错误
    路径 序列化
    css基础回顾
    React 随笔二
    Reactnative 随笔一
    值类型和引用类型 装箱和拆箱 类和结构的异同 接口抽象类异同
    多语言配置--LogisticsPlatform物流平台系统
    word-wrap&&word-break,奇偶行、列设置样式
    easyUI 的tree 修改节点,sql递归查询
    跳转页面,传递参数——android
  • 原文地址:https://www.cnblogs.com/wangke0917/p/10519172.html
Copyright © 2020-2023  润新知