同源策略,它是由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>
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對象
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直接請求普通文件存在跨域無權限訪問的問題
- JSONP只能實現GET請求,而CORS支持全部類型的HTTP請求
- 使用CORS,開發者可使用普通的XMLHttpRequest發起請求和得到數據,比起JSONP有更好的錯誤處理
- 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 #返回數據
下面的代碼實現了經過添加中間件的方式實現跨域請求
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
MIDDLEWARE = [ ..... 'xxx.cors.CORSMiddleware', # xxx爲cors.py所在包的目錄 ]