Django之跨域請求同源策略
同源策略:
首先基於安全的原因,瀏覽器是存在同源策略這個機制的,同源策略阻止從一個源載入的文件或指令碼獲取或設定另一個源載入的文件的屬性。
而如果我們要跳過這個策略,也就是說非要跨域請求,那麼就需要通過JSONP或者CORS來實現了。
一個源的定義
如果兩個頁面的協議,埠(如果有指定)和域名都相同,則兩個頁面具有相同的源。
舉個例子:
下表給出了相對http://a.xyz.com/dir/page.html同源檢測的示例:
URL | 結果 | 原因 |
---|---|---|
http://a.xyz.com/dir2/other.html |
成功 | |
http://a.xyz.com/dir/inner/another.html |
成功 | |
https://a.xyz.com/secure.html |
失敗 | 不同協議 ( https和http ) |
http://a.xyz.com:81/dir/etc.html |
失敗 | 不同埠 ( 81和80) |
http://a.opq.com/dir/other.html |
失敗 | 不同域名 ( xyz和opq) |
JSONP
什麼是JSONP
首先提一下JSON這個概念,JSON是一種輕量級的資料傳輸格式,被廣泛應用於當前Web應用中。JSON格式資料的編碼和解析基本在所有主流語言中都被實現,所以現在大部分前後端分離的架構都以JSON格式進行資料的傳輸。
合格的json物件:
["one", "two", "three"] { "one": 1, "two": 2, "three": 3 } {"names": ["張三", "李四"] } [ { "name": "張三"}, {"name": "李四"} ]
不合格的json物件:
{ name: "張三", 'age': 32 } // 屬性名必須使用雙引號 [32, 64, 128, 0xFFF] // 不能使用十六進位制值 { "name": "張三", "age": undefined } // 不能使用undefined { "name": "張三", "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'), "getName": function() {return this.name;} // 不能使用函式和日期物件 }
stringify與parse方法
JavaScript中關於JSON物件和字串轉換的兩個方法:
JSON.parse(): 用於將一個 JSON 字串轉換為 JavaScript 物件
JSON.parse('{"name":"Q1mi"}'); JSON.parse('{name:"Q1mi"}') ; // 錯誤 JSON.parse('[18,undefined]') ; // 錯誤
JSON.stringify(): 用於將 JavaScript 值轉換為 JSON 字串。
JSON.stringify({"name":"Q1mi"})
那麼JSONP是什麼呢?
首先丟擲瀏覽器同源策略這個概念,為了保證使用者訪問的安全,現代瀏覽器使用了同源策略,即不允許訪問非同源的頁面,詳細的概念大家可以自行百度。這裡大家只要知道,在ajax中,不允許請求非同源的URL就可以了,比如www.a.com下的一個頁面,其中的ajax請求是不允許訪問www.b.com/c.php這樣一個頁面的。
JSONP就是用來解決跨域請求問題的,那麼具體是怎麼實現的呢?
JSONP原理
ajax請求受同源策略影響,不允許進行跨域請求,而script標籤src屬性中的連結卻可以訪問跨域的js指令碼,利用這個特性,服務端不再返回JSON格式的資料,而是返回一段呼叫某個函式的js程式碼,在src中進行了呼叫,這樣實現了跨域。
JSONP具體實現:
前端:
後臺:
總結:
一句話就是利用script標籤繞過同源策略,獲得一個類似這樣的資料。
ajax裡邊的callbacks本質上是(偽裝成script標籤src屬性發送請求的方式)傳送一個回撥方法,引數data就是想得到的json資料。
CORS 定義
Cross-Origin Resource Sharing(CORS)跨來源資源共享是一份瀏覽器技術的規範,提供了 Web 服務從不同域傳來沙盒指令碼的方法,以避開瀏覽器的同源策略,是 JSONP 模式的現代版。與 JSONP 不同,CORS 除了 GET 要求方法以外也支援其他的 HTTP 要求。另一方面,JSONP 可以在不支援 CORS 的老舊瀏覽器上運作。現代的瀏覽器都支援 CORS。
CORS 對比 JSONP
都能解決 Ajax直接請求普通檔案存在跨域無許可權訪問的問題
- JSONP只能實現GET請求,而CORS支援所有型別的HTTP請求
- 使用CORS,開發者可以使用普通的XMLHttpRequest發起請求和獲得資料,比起JSONP有更好的錯誤處理
- JSONP主要被老的瀏覽器支援,它們往往不支援CORS,而絕大多數現代瀏覽器都已經支援了CORS
CORS的實現
CORS有很多種實現方式,這裡介紹一種最簡單最直觀的的方式,就是修改views.py中對應函式,給它的響應頭部新增Access-Control-Allow-Origin餐具允許其他域通過Ajax請求資料,如下:
前端:
注:上面圖片中資料傳輸過來為none( ),利用Jaon.parse()進行轉物件 提取data 資料
後臺:
注:response["Access-Control-Allow-Origin"]="http://127.0.0.1:8006" #指定ip可訪問,‘*’ 為所有ip均可