CORS方法

CORS

隨着技術的發展,如今的瀏覽器能夠支持主動設置從而容許跨域請求,即:跨域資源共享(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'] = "*「

2、簡單請求 OR 非簡單請求

條件:
    一、請求方式: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)
相關文章
相關標籤/搜索