隨着技術的發展,如今的瀏覽器能夠支持主動設置從而容許跨域請求,即:跨域資源共享(CORS,Cross-Origin Resource Sharing),其本質是設置響應頭,使得瀏覽器容許跨域請求。javascript
index.html html
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="{% static 'jquery-3.2.1.js' %}"></script> </head> <body> <h1>維基解密</h1> <script> $.ajax({ url: "http://127.0.0.1:8000/get_data/", type: 'GET', success: function(data){ console.log(data); } }) </script> </body> </html>
views.py前端
def data(request): return HttpResponse("機密數據")
前端結果java
這裏提示咱們缺乏一個請求頭因此咱們在views中將這個請求頭帶上jquery
views.pyweb
def data(request): response = HttpResponse("機密數據") response['Access-Control-Allow-Origin'] = " http://127.0.0.1:8888" return response
這裏咱們只是將127.0.0.1:8888這個地址的請求能夠跨域進行訪問,也能夠對全部的都不如今即:ajax
response['Access-Control-Allow-Origin'] = "*「
條件: 一、請求方式:HEAD、GET、POST 二、請求頭信息: Accept Accept-Language Content-Language Last-Event-ID Content-Type 對應的值是如下三個中的任意一個 application/x-www-form-urlencoded multipart/form-data text/plain 注意:同時知足以上兩個條件時,則是簡單請求,不然爲複雜請求
實例:PUT請求後端
index.html 跨域
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="{% static 'jquery-3.2.1.js' %}"></script> </head> <body> <h1>維基解密</h1> <script> $.ajax({ url: "http://127.0.0.1:8000/get_data/", type: 'PUT', //這是一個複雜請求 success: function(data){ console.log(data); } }) </script> </body> </html>
咱們查看發送到請求頭信息以下:瀏覽器
這裏由於是複雜請求因此咱們須要在後端代碼增長一個預檢的過程
views.py
def data(request): if request.method == "OPTIONS": # 預檢 response = HttpResponse() response['Access-Control-Allow-Origin'] = "*" response['Access-Control-Allow-Methods'] = "PUT" return response elif request.method == "PUT": response = HttpResponse("機密數據") response['Access-Control-Allow-Origin'] = "*" return response
再看前端的頁面:
帶有請求頭的複雜請求
index.html
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="{% static 'jquery-3.2.1.js' %}"></script> </head> <body> <h1>維基解密</h1> <script> $.ajax({ url: "http://127.0.0.1:8000/get_data/", type: 'GET', headers:{'xxx':666}, success: function(data){ console.log(data); } }) </script> </body> </html>
前端渲染頁面顯示:
跨域傳輸cookie
在跨域請求中,默認狀況下,HTTP Authentication信息,Cookie頭以及用戶的SSL證書不管在預檢請求中或是在實際請求都是不會被髮送。
瀏覽器端:XMLHttpRequest的withCredentials爲true
服務器端:Access-Control-Allow-Credentials爲true
注意:服務器端響應的 Access-Control-Allow-Origin 不能是通配符 *
index.html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <p> <input type="submit" onclick="XmlSendRequest();" /> </p> <p> <input type="submit" onclick="JqSendRequest();" /> </p> <script type="text/javascript" src="jquery-1.12.4.js"></script> <script> function XmlSendRequest(){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState == 4) { var result = xhr.responseText; console.log(result); } }; xhr.withCredentials = true; xhr.open('PUT', "http://c2.com:8000/test/", true); xhr.setRequestHeader('k1', 'v1'); xhr.send(); } function JqSendRequest(){ $.ajax({ url: "http://c2.com:8000/test/", type: 'PUT', dataType: 'text', headers: {'k1': 'v1'}, xhrFields:{withCredentials: true}, success: function(data, statusText, xmlHttpRequest){ console.log(data); } }) } </script> </body> </html>
views.py
class MainHandler(tornado.web.RequestHandler): def put(self): self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com") self.set_header('Access-Control-Allow-Credentials', "true") self.set_header('xxoo', "seven") self.set_header('bili', "daobidao") self.set_header('Access-Control-Expose-Headers', "xxoo,bili") self.set_cookie('kkkkk', 'vvvvv'); self.write('{"status": true, "data": "seven"}') def options(self, *args, **kwargs): self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com") self.set_header('Access-Control-Allow-Headers', "k1,k2") self.set_header('Access-Control-Allow-Methods', "PUT,DELETE") self.set_header('Access-Control-Max-Age', 10)