zoukankan      html  css  js  c++  java
  • 前后台分离式开发(文件的上传下载),cookie(存放在前台),session(存放在后台)

    一:前后台分离开发的概念

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

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

    主要代码(前端中要导入bootstrap):

    前端:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>主页</title>
        <link rel="stylesheet" href="./bootstrap-3.3.7-dist/css/bootstrap.css">
    </head>
    <body>
    
    <button class="btn btn-primary">主页</button>
    <a href="./login.html">登录页面</a>
    <a href="./upload.html">上传页面</a>
    <a href="http://127.0.0.1:8731/download">链接标签页面</a>
    <button class="btn">普通标签页面</button>
    <script src="bootstrap-3.3.7-dist/js/jquery-3.3.1.js"></script>
    <script>
        $('.btn').click(function () {
            window.location.href='http://127.0.0.1:8731/dowmload/'
        })
    </script>
    
    </body>
    </html>
    index
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录</title>
    </head>
    <body>
    <h1>登录页面</h1>
    <form action="">
        <input class="usr" type="text" name="usr">
        <input class="pwd" type="password" name="pwd">
        <input class="btn" type="button" value="登录">
    </form>
    </body>
    <script src="bootstrap-3.3.7-dist/js/jquery-3.3.1.js"></script>
    <script>
        $('.btn').click(function () {
            $.ajax({
                url:'http://127.0.0.1:8731/login/',
                type:'post',
                data:{
                    usr:$('.usr').val(),
                    pwd:$('.pwd').val()
                },
                success:function (data) {
                    console.log(data);
                    // 可以完成页面的局部刷新
                    if (data.status == 'ok') {
                        $('h2').text(data.usr)
                    }
                }
            })
        })
    </script>
    </html>
    login
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>upload</title>
    </head>
    <body>
    
    <form action="">
        <input type="file" class="file" multiple>
        <input class="btn" type="button" value="上传">
    </form>
    <script src="bootstrap-3.3.7-dist/js/jquery-3.3.1.js"></script>
    <script>
        // $('.btn').click(function () {
        //     var file = $('.file').get(0).files[0];//js对象下files的第一个文件
        //     console.log(file)
        //
        // })
    
            $('.btn').click(function () {
            // alert('开始上传')
            // var file = $('.file').get(0).files[0];  // js对象下files中的第一个文件
            // console.log(file);
            // var form_data = new FormData();
            // form_data.append('file', file);
            var files = $('.file').get(0).files;
            for (var i = 0; i < files.length; i++) {
                var form_data = new FormData();
                form_data.append('file', files[i]);
                upload_action(form_data)
            }
        });
    
        function upload_action(form_data) {
            $.ajax({
                url: 'http://127.0.0.1:8731/upload/',
                type: 'post',
                // data: '文件信息',
                data: form_data,
                // 告诉jq,不需要帮我们再处理数据及数据格式
                contentType: false,
                processData: false,
                success: function (data) {
                    console.log(data);
                }
            })
        }
    </script>
    
    </body>
    </html>
    upload

    后台:

    from django.shortcuts import render,HttpResponse
    from django.http import JsonResponse
    # Create your views here.
    
    
    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})
    
    
    def upload(request):
        file_io = request.FILES.get('file', None)
        print(file_io)
        if file_io:
            with open(file_io.name, 'wb') as f:
                for line in file_io:
                    f.write(line)
    
        return JsonResponse({'status': 'error', 'msg': '上传成功'})
    
    # 下载
    from django.http import FileResponse
    def download(request):
        # 此处固定死了文件(写死了)
        file = open('123.md', 'rb')
        response = FileResponse(file)
        # 设置响应文件类型数据的响应头
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="%s"' % file.name
        return response
    views

    settings设置(设置跨域问题):

    要允许跨域源:

    CORS_ORIGIN_ALLOW_ALL = True

    要记得去url中配置路由

     二:跨域请求数据

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

        1.协议不同

        2.端口不同

        3.主机不同

      Django解决跨域问题:

    安装django-cors-headers模块
    
    在settings.py中配置
    # 注册app
    INSTALLED_APPS = [
        ...
        'corsheaders'
    ]
    # 添加中间件
    MIDDLEWARE = [
        ...
        'corsheaders.middleware.CorsMiddleware'
    ]
    # 允许跨域源
    CORS_ORIGIN_ALLOW_ALL = True
    跨域问题解决

    三:文件上传

    浏览器:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>upload</title>
    </head>
    <body>
    
    <form action="">
        <input type="file" class="file" multiple>
        <input class="btn" type="button" value="上传">
    </form>
    <script src="bootstrap-3.3.7-dist/js/jquery-3.3.1.js"></script>
    <script>
        // $('.btn').click(function () {
        //     var file = $('.file').get(0).files[0];//js对象下files的第一个文件
        //     console.log(file)
        //
        // })
    
            $('.btn').click(function () {
            // alert('开始上传')
            // var file = $('.file').get(0).files[0];  // js对象下files中的第一个文件
            // console.log(file);
            // var form_data = new FormData();
            // form_data.append('file', file);
            var files = $('.file').get(0).files;
            for (var i = 0; i < files.length; i++) {
                var form_data = new FormData();
                form_data.append('file', files[i]);
                upload_action(form_data)
            }
        });
    
        function upload_action(form_data) {
            $.ajax({
                url: 'http://127.0.0.1:8731/upload/',
                type: 'post',
                // data: '文件信息',
                data: form_data,
                // 告诉jq,不需要帮我们再处理数据及数据格式
                contentType: false,
                processData: false,
                success: function (data) {
                    console.log(data);
                }
            })
        }
    </script>
    
    </body>
    </html>
    upload

    后台:

    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

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

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

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

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

    # Django用HttpResponse对象操作Cookie
    response = HttpResponse('所有的响应都是HttpResponse对象')
    # 设置cookie:key、vaule与过期时间
    response.set_cookie(key, value, max_age)
    # 删除cookie:key
    response.delete_cookie(key)
    # 设置加盐cookie:key、vaule与盐字符串(就是简易的加密)
    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
    '''

    cookie运用:

    需求:

    1. /index/访问主页(可直接访问),主页中存在四个转跳
        -- 登录(/login/)
        -- 个人主页(/user/)
        -- 订单详情(/order/)
        -- 注销(/logout/)
    2. 进入个人主页、订单详情页面时,如果未登录,需先登录,然后自动回到个人主页或订单详情页面,反之直接进入

    核心代码:

    # 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
    核心代码

    六:session

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

      session的作用:结合cookie使用,解决cookie的不安全性

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

    ''' 常用操作
    # 1. 设置
    request.session['key1'] = 'value1'
    request.session['key2'] = 'value2'
    # 过程:
    # i) 生成一个随机字符串,作为主键
    # ii) 在django_session表中插入有三个字段的一条数据(一条数据对应一个浏览器会话)
        -- session_key:主键-随机字符串
        -- session_data:该会话拥有的所有key-value形成的大字典的加密字符串
        -- expire_date:过去时间,默认14天
    # iii) 往浏览器中写入一条cookie,sessionid=主键的随机字符串
    
    2. 获取
    request.session.get('key', None)
    
    3. 删除
    request.session.delete()  # 只删除当前会话对应的一条记录
    request.session.flush()  # 除了删除当前会话对应的一条记录外,还删除对应浏览器中的cookie
    
    5. 其他
    request.session.session_key  # 获取当前会话对应的session_key
    request.session.exists('session_key')  # 判断某session_key是否存在
    request.session.clear_expired()  # 情况所有过去的Session
    '''
    
    
    ''' settings.py配置
    # 1. 数据库存储
    # SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # 引擎(默认)
    #
    # 2. 缓存存储
    # SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    # SESSION_CACHE_ALIAS = 'default'  # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
    #
    # 3. 文件存储
    # SESSION_ENGINE = 'django.contrib.sessions.backends.file'  # 引擎
    # SESSION_FILE_PATH = '/'  # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
    #
    # 4. 缓存 + 数据库存储
    # SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'  # 引擎
    #
    # 5. 加密Cookie
    # SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'  # 引擎
    #
    # SESSION_COOKIE_NAME = "sessionid"  # cookie的key名,值为随机字符串
    # SESSION_COOKIE_PATH = "/"  # 作用路径,/代表所有路径下均起作用)
    # SESSION_COOKIE_DOMAIN = None  # 作用域名
    # SESSION_COOKIE_SECURE = False  # 布尔类型,浏览器是否通过HTTPS方式回传cookie
    # SESSION_COOKIE_HTTPONLY = True  # 布尔类型,JS能否直接访问该条cookie
    # SESSION_COOKIE_AGE = 1209600  # 数据库session字段的过期时间
    # SESSION_EXPIRE_AT_BROWSER_CLOSE = True  # 浏览器关闭后cookie是否过期,默认False不过期
    # SESSION_SAVE_EVERY_REQUEST = False  # 每一次请求,是否更新session字段的过期时间,默认False不更新
    
    '''
    session介绍
  • 相关阅读:
    关于排列组合与分配问题
    Stirling数
    UVA 294 求约数的个数
    Linux中profile与bashrc的作用
    一致性哈希(consistent hashing)算法
    TCP三次握手与四次挥手
    MySQL查询昨天、今天、7天、近30天、本月、上一月数据
    java基础-注解Annotation原理和用法
    java基础-浅复制与深复制的理解
    Linux命令行提示符设置
  • 原文地址:https://www.cnblogs.com/liuxiaolu/p/10525046.html
Copyright © 2011-2022 走看看