跨域資源共享(CORS)


同源策略

同源策略是瀏覽器的一個安全策略,只允許當前頁面或當前域下發送請求,如果向其他域發送請求,會被瀏覽器攔截

同源的意思:協議、IP地址、端口三者一致,瀏覽器才會認為是同一個域,三者中有一個不一致就是不同域

實例:比如說我們要通過127.0.0.1:8001/test/中的一個點擊事件,提交一個ajax請求,要去拿127.0.0.1:8010/test2/的返回數據,這時候就會遇到一個問題——跨域資源共享的問題,程序的報錯信息如下:

Access to XMLHttpRequest at 'http://127.0.0.1:8010/test2/' from origin 'http://127.0.0.1:8001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
# CORS策略已阻止從源站“http://127.0.0.1:8001”訪問位於“http://127.0.0.1:8010/test2/”的xmlhttpRequest:請求的資源上不存在“訪問控制允許源站”頭

views.py(該程序運行的網址為http://127.0.0.1:8010/test2

from django.shortcuts import render, HttpResponse
​
​
def test2(request):
    return HttpResponse('這是另一個網站地址')

127.0.0.1:8001/test/中通過ajax向127.0.0.1:8010/test2/發送GET請求,其實數據已經被拿回來了,報錯的原因就是返回的數據被瀏覽器攔截了,這就是跨域問題的本質。那如何解決這個問題,最簡單的處理方法就是在被ajax請求訪問的視圖函數返回的時候讓它帶上一個參數:response['Access-Control-Allow-Origin'] ='http://127.0.0.1:8001'

將8010端口運行的views.py做如下修改

def test2(request):
    response = HttpResponse('這是另一個網站地址')
    # 只允許一個域
    response['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8001'
    # 允許所有的域
    # response['Access-Control-Allow-Origin'] = '*'
    return response

這時候再去通過ajax訪問127.0.0.1:8010/test2/網站就不會報錯了!執行效果如下:

其實,CORS有兩種請求方式,以上處理的這只是簡單請求

簡單請求與非簡單請求

簡單請求必須滿足的條件

# 1、請求方法是以下一種:
    GET
    POST
    HEAD
# 2、http的頭信息不超出以下幾種:
    Accept
    Accept-Language
    Content-Language
    Last-Event-ID
    Content-Type:application/x-www-form-urlencoded、multipart/form-data、text/plain   # 只限於這三個值

除了以上的所有出現的信息都是非簡單請求!

那針對不同的請求會有不同的解決方法,所謂的簡單請求就是只發送一次請求,而非簡單請求是發送兩次請求,在發送數據之前會先發一次請求用於做“預檢(OPTIONS)”,只有“預檢”通過后才再發送一次請求用於數據傳輸

預檢

請求方式:OPTIONS

“預檢”其實是做檢查,檢查如果通過則允許傳輸數據,檢查不通過則不再發送真正想要發送的消息

如何“預檢”

如果復雜請求是PUT等請求,則服務端需要設置允許某請求,否則“預檢”不通過

Access-Control-Request-Method

如果復雜請求設置了請求頭,則服務端需要設置允許某請求頭,否則“預檢”不通過

Access-Control-Request-Headers

簡單請求支持跨域

服務器設置響應頭:Access-Control-Allow-Origin = '域名' 或 '*'

非簡單請求支持跨域

由於復雜請求時,首先會發送“預檢”請求,如果“預檢”成功,則發送真實數據。

  • “預檢”請求時,允許請求方式則需服務器設置響應頭:Access-Control-Request-Method
  • “預檢”請求時,允許請求頭則需服務器設置響應頭:Access-Control-Request-Headers

在Django中解決CORS問題

可以通過上述方法在返回的結果中添加允許信息來解決簡單請求,還可以在Django的中間件中處理簡單請求和非簡單請求

from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):
    def process_response(self,request,response):
     # 非簡單請求 if request.method=="OPTIONS": #可以加* response["Access-Control-Allow-Headers"]="Content-Type" response["Access-Control-Allow-Origin"] = "允許訪問的URL" return response

  

 

 


免責聲明!

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



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