先後臺分離開發--文件上傳與下載,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

'''
相關文章
相關標籤/搜索