CORS方法

CORS

随着技术的发展,现在的浏览器可以支持主动设置从而允许跨域请求,即:跨域资源共享(CORS,Cross-Origin Resource Sharing),其本质是设置响应头,使得浏览器允许跨域请求。

**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',
            success: function(data){
                console.log(data);
            }
        })
    </script>
</body>
</html>

views.py

def data(request):

    return HttpResponse("机密数据")

前端结果

这里提示我们缺少一个请求头所以我们在views中将这个请求头带上

views.py

def data(request):
    response = HttpResponse("机密数据")
    response['Access-Control-Allow-Origin'] = " http://127.0.0.1:8888"

    return response

这里我们只是将127.0.0.1:8888这个地址的请求可以跨域进行访问,也可以对所有的都不现在即:

 response['Access-Control-Allow-Origin'] = "*“

二、简单请求 OR 非简单请求

条件:
    1、请求方式:HEAD、GET、POST
    2、请求头信息:
        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)
posted @ 2017-11-22 16:55  Sun珊珊来迟  阅读(302)  评论(0编辑  收藏  举报