先后台分离开发--文件上传与下载,cookie,session

1、先后台分离开发的概念

'''
1. 前台页面运行在前台服务器上,负责页面的渲染(静态文件的加载)与转跳
2. 后台代码运行在后台服务器上,负责数据的处理(提供数据请求的接口)
'''
#若是没有先后台分离,全部的页面都要加载到django里面,页面的加载与处理都要在django中完成

2、跨域请求数据

1.什么是跨域?

'''
一般状况下,A网页访问B服务器资源时,不知足如下三个条件其一就是跨域访问
1. 协议不一样
2. 端口不一样
3. 主机不一样
'''

2.解决跨域问题?

'''
①没有关闭settings中的csrf中间件,数据不能从前台到后台也不会有响应
②关闭了中间件可是没有安装django-cors-headers模块并进行配置,数据能够从前台传到后台可是不会有响应
'''
'''
1. 前台与后台有跨域问题, 解决跨域
安装django-cors-headers模块
在settings.py中配置
# 注册app
INSTALLED_APPS = [
    ...
    'corsheaders'
]
# 添加中间件
MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware'
]
# 容许跨域源
CORS_ORIGIN_ALLOW_ALL = True

2. 前台代码

<h2 class="pull-right">用户</h2>
<form action="">
    <input class="usr" type="text" name="usr">
    <input class="pwd" type="text" name="pwd">
    <input  class="btn" type="button" value="登陆">
</form>

<script>
    $('.btn').click(function () {
        $.ajax({
            url: 'http://127.0.0.1:8000/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>

3. 后台代码
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})
'''

3、文件上传

1.一个文件

浏览器html

<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) #get获取的是列表中的最后一个
    if file:
        with open(file.name, 'wb') as f:
            for line in file:
                f.write(line)
    return JsonResponse({
        'status': 'OK',
        'msg': 'upload success'
    })

2.多个文件

浏览器ajax

<form action="">
    <input type="file"  class="file" multiple>
    <input  class="btn" type="button" value="上传">
</form>

<script>
    $('.btn').click(function () {
        // var file =$('.file').get(0).files[0];
        // 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();
            //'file'后台能够用file获取
            form_data.append('file', files[i]);
            upload_action(form_data)
        }

        function upload_action(form_data) {
            $.ajax({
                url: 'http://127.0.0.1:8000/upload/',
                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) #get获取的是列表中的最后一个
    if file:
        with open(file.name, 'wb') as f:
            for line in file:
                f.write(line)
    return JsonResponse({
        'status': 'OK',
        'msg': 'upload success'
    })

4、文件下载

浏览器django

<a href="http://127.0.0.1:8000/download/">链接下载</a>
<button type="button" class="download">普通标签下载</button>
<script>
    $('.download').click(function () {
        window.location.href = 'http://127.0.0.1:8000/download/'
    })
</script>

后台跨域

from django.http import FileResponse 
def download(request):
    file = open('123.zip', 'rb')
    response = FileResponse(file)
    file.close()
    #设置响应文件类型数据的响应头
    response['Content-Type'] = 'application/octet-stream'
    response['Content-Disposition'] = 'attachment;filename="%s"' % file.name
    return response

5、cookie

1.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
'''

2.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

6、session介绍

'''
# 在视图函数中经过request对象操做session
# 1. 设置session
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. 获取session
request.session.get('key', None)

# 3. 删除session
request.session.delete()  # 只删除当前会话对应的一条记录
request.session.flush()  # 除了删除当前会话对应的一条记录外,还删除对应浏览器中的cookie,建议使用

# 4. 清除django-session表中全部过时的session字段
request.session.clear_expired()  # 状况全部过去的Session

# 5. 了解
request.session.session_key  # 获取当前会话对应的session_key
request.session.exists('session_key')  # 判断某session_key是否存在
'''

session的settings配置

''' 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 = False  # 浏览器关闭后cookie是否过时,默认False不过时,建议True
# SESSION_SAVE_EVERY_REQUEST = False  # 每一次请求,是否更新session字段的过时时间,默认False不更新,建议True

'''
相关文章
相关标签/搜索