前后台分離式開發(文件的上傳下載),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介紹

 


免責聲明!

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



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