K8S 部署Dashboard UI
CORS簡介
CORS(Cross-Origin Resource Sharing):跨域資源共享
CORS是一種允許當前域(domain)的資源(比如html/js/web service)被其他域(domain)的指令碼請求訪問的機制,通常由於同域安全策略(the same-origin security policy)瀏覽器會禁止這種跨域請求。
1 同源策略:請求的url地址,必須與瀏覽器上的url地址處於同域上,也就是域名,埠,協議相同. 2 CORS:跨域資源共享,允許不同的域來我的伺服器拿資料 3 CORS請求分成兩類: 簡單請求(simple request)和 非簡單請求(not-so-simple request) # 簡單請求: 只要同時滿足以下兩大條件,就屬於簡單請求 (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# 非簡單請求 如果傳送post請求,資料格式是json---》非簡單請求, 非簡單請求發兩次,一次OPTIONS請求,一次真正的請求
跨域問題及解決
我們開啟兩個服務端,域名不同,通過埠2來訪問埠1
埠1:http://127.0.0.1:8000/user/test/ 埠2:http://127.0.0.1:8080/cors/ 上面2者域名不同,我們通過埠2來訪問埠1 # 埠2: <body> <button onclick="test()">點選</button> <script> function test(){ $.ajax({ url:'http://127.0.0.1:8000/user/test/', type:'get', data:'', success:function(ll){ console.log(ll) alert('ok') } }) } </script> </body> # 埠2通過ajax請求來訪問埠1
結果如下:
如上面所示,埠1成功傳送了請求,並且埠2接收到請求並響應,
但是響應回來的時候瀏覽器的同源策略阻止了埠1的訪問,
那麼,我們該如何解決這個問題呢?
簡單請求的解決方式
如果是對方發起的是簡單請求
我們只要在埠1的響應頭裡設定允許埠2域名的跨站資源請求即可,如下:
# 埠1修改前: def test(request): print('我運行了') res = HttpResponse('測試跨域資源共享') return res # 埠1修改後: def test(request): print('我運行了') res = HttpResponse('測試跨域資源共享') # 在埠1的請求頭內將該引數設定為允許8080埠訪問 res['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8080' return res # 只要埠1的服務端設定了允許跨域資源訪問, # 被允許的埠就能訪問到埠1服務端的資源
非簡單請求解決方式
上面我們解決了簡單請求跨域資源被禁止的情況,
但是當我們發起非簡單請求時,還是會出現跨域資源被禁止的情況,如下:
埠1:http://127.0.0.1:8000/user/test/ 埠2:http://127.0.0.1:8080/cors/ # 埠2通過ajax向埠1發起post請求,攜帶Json格式資料 # 所以是非簡單請求 <script> function test(){ $.ajax({ url:'http://127.0.0.1:8000/user/test/', type:'post', contentType:'application/json', data:JSON.stringify({'yessir':'nb'}), success:function(res){ console.log(res) alert('ok') } }) } </script> # 埠1服務端已經添加了允許跨域訪問的響應頭 def test(request): print('我運行了') print('請求方式為:',request.method) res = HttpResponse('測試跨域資源共享') # 在埠1的請求頭內將該引數設定為允許8080埠訪問 res['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8080' return res # 我們發現當發起非簡單請求的時候, # 雖然我們在埠1設定了請求頭, # 還是會觸發瀏覽器的同源策略的禁止跨域訪問資源的情況
我們埠2發起的請求方式為POST請求,但是埠1顯示的卻是OPTIONS,
其實當發起非簡單請求的時候,非簡單請求會發起2次請求,一次是options,
另一次才是真正的請求,所以我們只要在埠1服務端的響應頭內加上該引數,
就可以訪問到埠1的服務端資源了,具體如下:
# 埠1修改前: def test(request): print('請求方式為:',request.method) print('我運行了') res = HttpResponse('測試跨域資源共享') # 在埠1的請求頭內將該引數設定為允許8080埠訪問 res['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8080' return res # 埠1修改後: def test(request): print('請求方式為:',request.method) print('我運行了') res = HttpResponse('測試跨域資源共享') if request.method == 'OPTIONS': res['Access-Control-Allow-Headers'] = 'Content-Type' # 在埠1的請求頭內將該引數設定為允許8080埠訪問 res['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8080' return res # 在埠1的響應頭內新增該引數,即可解決瀏覽器同源策略禁止跨域訪問資源問題
在自定義中介軟體中配置
但是如果我們需要跨域訪問很多的介面,那我們就需要給每個介面的響應頭都新增上這些引數,
這太過繁瑣了,所以我們就可以在django中介軟體中重寫process_response方法,
給響應頭加上這些引數,這樣我們就不需要為每個介面都配置上這些引數了
如下:在小luffyapi的utils包下,建立midware.py
# utils/midware.py from django.utils.deprecation import MiddlewareMixin
class MyMiddle(MiddlewareMixin): def process_response(self, request, response): response['Access-Control-Allow-Origin'] = '*' if request.method == "OPTIONS": # 可以加* response["Access-Control-Allow-Headers"] = "Content-Type" response["Access-Control-Allow-Headers"] = "authorization" return response
在配置中註冊上自定義中介軟體
# settings/div.py MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # 註冊自定義中介軟體 'luffyapi.utils.midware.CorsMiddleware' ]
第三方外掛解決CORS
安裝django-cors-headers
第三方外掛django-cors-headers幫我們解決了CORS同源策略問題,
我們可以使用第三方外掛,這樣我們就不需要自己寫中介軟體
pip install django-cors-headers
註冊app
第三方外掛其實就是一個應用,需要在 INSTALLED_APPS 中註冊一下
# settings/div.py INSTALLED_APPS = [ ... 'corsheaders' ... ] CORS_ORIGIN_ALLOW_ALL = True CORS_ALLOW_METHODS = ( 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'VIEW', ) CORS_ALLOW_HEADERS = ( 'authorization', 'content-type', )