django之同源策略

什麼是同源策略php

同源策略,它是由Netscape提出的一個著名的安全策略。如今全部支持JavaScript 的瀏覽器都會使用這個策略。所謂同源是指,域名,協議,端口相同。當一個瀏覽器的兩個tab頁中分別打開來 百度和谷歌的頁面,當瀏覽器的百度tab頁執行一個腳本的時候會檢查這個腳本是屬於哪一個頁面的,即檢查是否同源,只有和百度同源的腳本纔會被執行。若是非同源,那麼在請求數據時,瀏覽器會在控制檯中報一個異常,提示拒絕訪問。html

簡單來講,端口不一樣或者域名不一樣,就會有庭院策略問題ajax

什麼是JSONPjson

首先提一下JSON這個概念,JSON是一種輕量級的數據傳輸格式,被普遍應用於當前Web應用中。JSON格式數據的編碼和解析基本在全部主流語言中都被實現,因此如今大部分先後端分離的架構都以JSON格式進行數據的傳輸。後端

那麼JSONP是什麼呢? 
首先拋出瀏覽器同源策略這個概念,爲了保證用戶訪問的安全,現代瀏覽器使用了同源策略,即不容許訪問非同源的頁面,詳細的概念你們能夠自行百度。這裏你們只要知道,在ajax中,不容許請求非同源的URL就能夠了,好比www.a.com下的一個頁面,其中的ajax請求是不容許訪問www.b.com/c.php這樣一個頁面的。跨域

JSONP就是用來解決跨域請求問題的,那麼具體是怎麼實現的呢?瀏覽器

JSONP原理安全

ajax請求受同源策略影響,不容許進行跨域請求,而script標籤src屬性中的連接卻能夠訪問跨域的js腳本,利用這個特性,服務端再也不返回JSON格式的數據,而是返回一段調用某個函數的js代碼,在src中進行了調用,這樣實現了跨域。服務器

JSONP的具體實現
架構

<!DOCTYPE html>
<html>
<head>
    <title>GoJSONP</title>
</head>
<body>
 $(".jsonp_test").click(function () {
    $.ajax({
        url:"http://127.0.0.1:8008/service/",
        type:"get",
        dataType:"jsonp",     // 僞造ajax  基於script
        jsonp: 'callbacks',    //至關於?callbacks=alex
        //jsonpCallback:"alex",
        success:function (data) {
            console.log(data)
        }
    })
})
<button class='jsop_test'>測試</button>
</body> </html>
127.0.0.1:8000中的index.html
import json
def jsonp_test(request):
    func=request.GET.get("callbacks") #獲取請求的callbacks參數
    info={"name":"fuyong","age":18} #定義數據
    return HttpRespons
import json
def jsonp_test(request):
    func=request.GET.get("callbacks") #獲取請求的callbacks參數
    info={"name":"fuyong","age":18} #定義數據
    return HttpResponse("%s ('%s')"%(func,json.dumps(info))) #傳json對象
http://127.0.0.1:8008/service/的views

 JSONP總結

一句話就是利用script標籤繞過同源策略,得到一個相似這樣的數據。ajax裏邊的callbacks本質上是(假裝成script標籤src屬性發送請求的方式)發送一個回調方法,參數data就是想獲得的json數據。

CORS實現跨域請求

CORS:Cross-Origin Resource Sharing(CORS)跨來源資源共享是一份瀏覽器技術的規範,提供了 Web 服務從不一樣域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,是 JSONP 模式的現代版。與 JSONP 不一樣,CORS 除了 GET 要求方法之外也支持其餘的 HTTP 要求。用 CORS 可讓網頁設計師用通常的 XMLHttpRequest,這種方式的錯誤處理比 JSONP 要來的好 。另外一方面,JSONP 能夠在不支持 CORS 的老舊瀏覽器上運做。現代的瀏覽器都支持 CORS。

CORS對比JSONP

都能解決 Ajax直接請求普通文件存在跨域無權限訪問的問題

  1. JSONP只能實現GET請求,而CORS支持全部類型的HTTP請求
  2. 使用CORS,開發者可使用普通的XMLHttpRequest發起請求和得到數據,比起JSONP有更好的錯誤處理
  3. JSONP主要被老的瀏覽器支持,它們每每不支持CORS,而絕大多數現代瀏覽器都已經支持了CORS

 CORS的實現思路

CORS背後的基本思想是使用自定義的HTTP頭部容許瀏覽器和服務器相互瞭解對方,從而決定請求或響應成功與否。

例如 localhost:63343 經過Ajax請求http://192.168.10.61:8080服務器資源時就會出現異常,其實數據已經獲取到了,可是因爲同源策略的限制給禁止了,提示說header裏沒有Access-Control-Allow-Origin,那麼,咱們在發送響應的時候的只須要給header里加上這個參數就好了。

 CORS的實現

CORS有不少種實現方式,這裏介紹一種最簡單最直觀的的方式,就是修改views.py中對應函數,給它的響應頭部添加Access-Control-Allow-Origin餐具容許其餘域經過Ajax請求數據,以下:

def cors_test(request):
    info={"name":"egon","age":34,"price":200} #數據
    response=HttpResponse(json.dumps(info)) #序列化數據
    #response["Access-Control-Allow-Origin"]="http://127.0.0.1:8006" #指定ip可訪問
    #response["Access-Control-Allow-Origin"]="*"#全部ip都可訪問
    return  response #返回數據
views.py

下面的代碼實現了經過添加中間件的方式實現跨域請求

class MiddlewareMixin(object):
    def __init__(self, get_response=None):
        self.get_response = get_response
        super(MiddlewareMixin, self).__init__()
 
    def __call__(self, request):
        response = None
        if hasattr(self, 'process_request'):
            response = self.process_request(request)
        if not response:
            response = self.get_response(request)
        if hasattr(self, 'process_response'):
            response = self.process_response(request, response)
        return response
 
class CORSMiddleware(MiddlewareMixin):
 
    def process_response(self,request,response):
        # 添加響應頭
 
        # 容許你的域名來獲取個人數據
        response['Access-Control-Allow-Origin'] = "*"
 
        # 容許你攜帶Content-Type請求頭
        response['Access-Control-Allow-Headers'] = "Content-Type"
 
        # 容許你發送DELETE,PUT
        response['Access-Control-Allow-Methods'] = "DELETE,PUT"
 
        return response
cors.py
MIDDLEWARE = [
   .....
 
    'xxx.cors.CORSMiddleware',  # xxx爲cors.py所在包的目錄
]
settings
相關文章
相關標籤/搜索