一、緩存 介紹: 在動態網站中,用戶所有的請求,服務器都會去數據庫中進行相應的增,刪,查,改,渲染模板,執行業務邏輯,最后生成用戶看到的頁面. 當一個網站的用戶訪問量很大的時候,每一次的的后台操作,都會消耗很多的服務端資源,所以必須使用緩存來減輕后端服務器的壓力. 緩存是將一些常用的數據保存內存或者memcache中,在一定的時間內有人來訪問這些數據時,則不再去執行數據庫及渲染等操作,而是直接從內存或memcache的緩存中去取得數據,然后返回給用戶. 幾種緩存方式: 1、開發調試緩存 2、內存緩存 3、文件緩存 4、數據庫緩存 5、緩存到redis 1、開發調試(此模式為開發調試使用,實際上不執行任何操作) CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 緩存后台使用的引擎 'TIMEOUT': 300, # 緩存超時時間(默認300秒,None表示永不過期,0表示立即過期) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大緩存記錄的數量(默認300) 'CULL_FREQUENCY': 3, # 緩存到達最大個數之后,剔除緩存個數的比例,即:1/CULL_FREQUENCY(默認3) }, } } 2、內存緩存(將緩存內容保存至內存區域中) CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # 指定緩存使用的引擎 'LOCATION': 'unique-snowflake', # 寫在內存中的變量的唯一值 'TIMEOUT':300, # 緩存超時時間(默認為300秒,None表示永不過期) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大緩存記錄的數量(默認300) 'CULL_FREQUENCY': 3, # 緩存到達最大個數之后,剔除緩存個數的比例,即:1/CULL_FREQUENCY(默認3) } } } 3、文件緩存(把緩存數據存儲在文件中) CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定緩存使用的引擎 'LOCATION': '/var/tmp/django_cache', #指定緩存的路徑 'TIMEOUT':300, #緩存超時時間(默認為300秒,None表示永不過期) 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大緩存記錄的數量(默認300) 'CULL_FREQUENCY': 3, # 緩存到達最大個數之后,剔除緩存個數的比例,即:1/CULL_FREQUENCY(默認3) } } } 4、數據庫緩存 CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', # 指定緩存使用的引擎 'LOCATION': 'cache_table', # 數據庫表 'OPTIONS':{ 'MAX_ENTRIES': 300, # 最大緩存記錄的數量(默認300) 'CULL_FREQUENCY': 3, # 緩存到達最大個數之后,剔除緩存個數的比例,即:1/CULL_FREQUENCY(默認3) } } } 需要注意:創建緩存的數據庫表使用的語句: python manage.py createcachetable
緩存的粒度:
全站緩存 來的請求所需要的所有數據全部緩存
單頁面緩存 單獨一個頁面所需的數據緩存起來
局部緩存 頁面中某個位置的數據緩存起來
緩存的使用: 1.1、單頁面的緩存:在視圖函數上加上一個裝飾器即可 from django.views.decorators.cache import cache_page import time @cache_page(10) # 設置超時時間 def test(request): ctime = time.time() return render(request,'test.html',locals()) 需要注意,在settings里配置一下: CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', # 指定緩存使用的引擎 'LOCATION': 'C:\cache_location', # 指定緩存的路徑 'TIMEOUT': 300, # 緩存超時時間(默認為300秒,None表示永不過期) 'OPTIONS': { 'MAX_ENTRIES': 300, # 最大緩存記錄的數量(默認300) 'CULL_FREQUENCY': 3, # 緩存到達最大個數之后,剔除緩存個數的比例,即:1/CULL_FREQUENCY(默認3) } } }
1.2 cbv下實現單頁面緩存
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
import time
@method_decorator(cache_page(5),name='dispatch')
class ShowTime(APIView):
def get(self,request):
ctime = time.strftime('%Y-%m-%d %H:%M:%S')
return render(request,'show_time.html',{'ctime':ctime})
2、局部緩存 from django.core.cache import cache import time def test(request): ctime = time.time() return render(request,'test.html',{'time':ctime}) 雖然與單頁面的settings配置是一樣的,但在模板文件里存在一定的差異性。 模板層: {% load cache %} {{ time }} #這部分的內容沒有被緩存 {% cache 5 'test'%} #第一個參數表示緩存時間,第二個參數是key值(取緩存的時候,需要根據key值取) 當前時間:{{ time }} # 這部分的數據被緩存 {% endcache %} 3、全站緩存 需要在settings里配置兩個中間件,一個在最上方,一個在最下方 'django.middleware.cache.UpdateCacheMiddleware', # 重寫了process_response ''這里的是其他的中間件'' 'django.middleware.cache.FetchFromCacheMiddleware' # 重寫了process_request 同時還需要配置超時時間,同樣在settings里配置 CACHE_MIDDLEWARE_SECONDS = 5 超時時間設定為5秒 需要注意:不需要配置CACHES了! 緩存的高級用法: 對於前后端分離的項目: cache.set('test_data',{'name':'michael','age':18},5) #對應的key為 test_data,數據位字典里的數據,超時時間為5秒 cache.get('test_data') # 取對應的緩存數據
二、跨域 跨域的產生是由於瀏覽器的同源策略,介紹下: 同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。 何為跨域: 通常情況下,A網頁訪問B服務器資源時,不滿足以下三個條件其一就是跨域訪問 1. 協議不同 2. 端口不同 3. 主機不同 跨域時,后端其實已經拿到前端發送的請求了,只是在返回數據時被攔截了!!! 解決方案:CORS(跨域資源共享) CORS需要瀏覽器和服務器同時支持。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低於IE10。 整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。 因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。 基本流程: 覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。 瀏覽器發出CORS簡單請求,只需要在頭信息之中增加一個Origin字段。 瀏覽器發出CORS非簡單請求,會在正式通信之前,增加一次HTTP查詢請求,稱為"預檢"請求(preflight)。瀏覽器先詢問服務器,當前網頁所在的域名是否在服務器的許可名單之中,以及可以使用哪些HTTP動詞和頭信息字段。只有得到肯定答復,瀏覽器才會發出正式的XMLHttpRequest請求,否則就報錯。 兩種請求詳解: 只要滿足以下兩大請求的,就是簡單請求: (1) 請求方法是以下三種方法之一: HEAD GET POST (2)HTTP的頭信息不超出以下幾種字段: Accept Accept-Language Content-Language Last-Event-ID Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain 只要不滿足上面兩個條件的,就屬於非簡單請求 瀏覽器對這兩種請求的處理,是不一樣的。 二者的區別: 簡單請求:一次請求 非簡單請求:兩次請求,在發送數據之前會先發一次請求用於做“預檢”,只有“預檢”通過后才再發送一次請求用於數據傳輸。 * 關於“預檢” - 請求方式:OPTIONS - “預檢”其實做檢查,檢查如果通過則允許傳輸數據,檢查不通過則不再發送真正想要發送的消息 - 如何“預檢” => 如果復雜請求是PUT等請求,則服務端需要設置允許某請求,否則“預檢”不通過 Access-Control-Request-Method => 如果復雜請求設置了請求頭,則服務端需要設置允許某請求頭,否則“預檢”不通過 Access-Control-Request-Headers 支持跨域,簡單請求 服務器設置響應頭:Access-Control-Allow-Origin = '域名' 或 '*' 支持跨域,復雜請求 由於復雜請求時,首先會發送“預檢”請求,如果“預檢”成功,則發送真實數據。 “預檢”請求時,允許請求方式則需服務器設置響應頭:Access-Control-Request-Method “預檢”請求時,允許請求頭則需服務器設置響應頭:Access-Control-Request-Headers
簡單請求: 視圖層: from django.shortcuts import HttpResponse def test1(request): print(request.method) bon = HttpResponse('ok') return bon 中間件: class CorsMiddleWare(MiddlewareMixin): def process_response(self,request,response): if request.method == 'GET': response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8001" return response 另外一個端口的django下的模板層: <script> $('#btn').click(function () { alert(111) $.ajax({ url:'http://127.0.0.1:8000/test1/', type:'get', data:{'name':'micahel'}, {#contentType:'application/json',#} success:function (datas) { console.log(datas) } }) }) </script>
非簡單請求: 視圖層: 在簡單的函數下: from django.shortcuts import HttpResponse def test1(request): print(request.method) # 會打印兩次 一次為OPTIONS,另一次為前端的請求方式 bon = HttpResponse('ok') return bon 中間件: from django.utils.deprecation import MiddlewareMixin class CorsMiddleWare(MiddlewareMixin): def process_response(self, request, response): if request.method == 'OPTIONS': print(request) # <WSGIRequest: OPTIONS '/test1/'> print(response) # <HttpResponse status_code=200, "text/html; charset=utf-8"> response["Access-Control-Allow-Headers"] = "Content-Type" if request.method == 'POST': print(request) # <WSGIRequest: POST '/test1/'> print(request.POST) # <QueryDict: {}> 因為我傳過來的數據是json類型的 print(request.body) # b'name=micahel' json類型的數據在request.body里面 response["Access-Control-Allow-Origin"] = "http://127.0.0.1:8001" return response 另外一個端口下的模板層: <script> $('#btn').click(function () { alert(111) $.ajax({ url:'http://127.0.0.1:8000/test1/', type:'post', data:{'name':'micahel'}, contentType:'application/json', success:function (datas) { console.log(datas) } }) }) </script>
待續:在cbv下實現跨域 !!! 因為走了一次預檢,所以第一次的method = options ,第二次為 post ,所以可考慮到cbv繼承view,在其內部定義一個options方法即可!
不過在實際操作開發過程中,在視圖類中不會寫options方法,而是直接在中間件里完成即可!
-redis的安裝和簡單使用
-內存數據庫
-Redis-x64-3.2.100---》mysql
-redis-desktop-manager-0.9.3.817----》navcate
-安裝完后
-redis-server 服務端
-redis-cli 客戶端