码迷,mamicode.com
首页 > Web开发 > 详细

ajax跨域原理(2) cors跨域资源共享

时间:2018-03-09 21:23:34      阅读:261      评论:0      收藏:0      [点我收藏+]

标签:若是   content   tar   第一次用   tornado   sed   console   color   url   

不需要设置前端太多,只需要在服务端是在请求头,使服务端的回复数据可以正常通过浏览器的限制,进入网站

首先说下简单请求和非简单请求:

简单请求:必须满足下列条件

1.请求方式:head,get,post

2.请求头

Accept

Accept-Language

Content-Language

Last-Event-ID

Content-Type:其对应值限制为3个application/x-www-form-urlencoded,multipart/form-data,text/plain

必须同时满足上面的两个条件叫做简单请求

简单请求:跨站请求时只需要一次请求

非简单请求:两次请求,在发送请求之前会先发送一次请求(预检),通过预检的才能再次发送一次请求进行数据传输

 

一:简单请求

前端:正常设置信息

    function CorsAjax(){
        $.ajax({
            url:http://www.py_test2.com:8081/cors,
            dataType:text,
            data:{},
            type:"post",
            success:function(data){
                console.log(data);
            }
        })
    }

后台服务端(跨域方)需要设置请求头:

    #简单请求
    def post(self, *args, **kwargs):
        self.set_header(Access-Control-Allow-Origin,"http://www.py_test1.com:8080,http://www.py_test1.com:8080")#设置一个或多个都可以,或者加上*代表所有的都允许
        self.write({"status":1,"message":"post"})

二:复杂请求:需要先发送一次预检

而预检的请求方式为options,所以我们需要在服务端设置一个options请求来处理预检信息

1.当前端的请求方式不满足条件时:

    //复杂请求,会发送两个请求,一个options一个put
    function CorsAjax2(){
        $.ajax({
            url:http://www.py_test2.com:8081/cors,
            dataType:text,
            data:{},
            type:"put",
            success:function(data){
                console.log(data);
            }
        })
    }

需要在服务端设置预检

    #复杂请求
    def options(self, *args, **kwargs):#第一次用于预检
        #先允许网站接入
        self.set_header(Access-Control-Allow-Origin, "http://www.py_test1.com:8080")
        #若是请求方法不满足get,post,head
        self.set_header(Access-Control-Allow-Methods,"PUT,DELETE")#还可以添加其他,比如DELETE,不能是*
    def put(self, *args, **kwargs):#第二次为请求,用于数据传输
       self.set_header(‘Access-Control-Origin‘,‘http://www.py_test1.com:8080‘) #也要设置源地址 self.write(
put ok)

2.当客户端请求头也不满足时:

    //复杂请求,会发送两个请求,一个options一个put
    function CorsAjax2(){
        $.ajax({
            url:http://www.py_test2.com:8081/cors,
            dataType:text,
            data:{},
            type:"put",
            headers:{k1:ddasf,"k2":fa},
            success:function(data){
                console.log(data);
            }
        })
    }

服务端需要设置关于请求头的信息

    #复杂请求
    def options(self, *args, **kwargs):#第一次用于预检
        #先允许网站接入
        #self.set_header(Access-Control-Allow-Origin,"*")  # 或者加上*代表所有的都允许
        #如果客户端允许传递cookie,那么这里请求头就不能是*,必须是指定的url
        self.set_header(Access-Control-Allow-Origin, "http://www.py_test1.com:8080")
        #若是请求方法不满足get,post,head
        self.set_header(Access-Control-Allow-Methods,"PUT,DELETE")#还可以添加其他,比如DELETE,不能是*
        #若是请求头也不满足简单请求,也需要设置
        self.set_header(Access-Control-Allow-Headers, "k1,k2")#客户端自定义请求头

对于客户端预检可以设置缓存时间,在相应时间内,不会再进行预检

        #可以设置缓存时间,原来需要一次预检一次请求,现在只需要一次请求
        self.set_header(Access-Control-Max-Age,10)#10秒内不再产生预检

对于请求头,若是服务端想要自定义请求都传入客户端:需要进行以下操作

    def put(self, *args, **kwargs):#第二次为请求
        #服务端自定义响应头
        #self.set_header(xxoo,seven)
        #self.set_header(bili,daobidao)#这样是客户端无法接收
        #还需要设置一条
        #self.set_header(Access-Control-Expose-Headers,"xxoo,bili")

3.当客户端允许携带cookie时

需要在客户端设置XMLHttpRequest的withCredentials为true

    //复杂请求,会发送两个请求,一个options一个put
    function CorsAjax2(){
        $.ajax({
            url:http://www.py_test2.com:8081/cors,
            dataType:text,
            data:{},
            type:"put",
            headers:{k1:ddasf,"k2":fa},
            xhrFields:{withCredentials:true},//默认是不允许携带cookie和ssl证书等,需要设置,服务端也要相应设置
            success:function(data){
                console.log(data);
            }
        })
    }

注意在服务端响应时不允许设置Access-Control-Allow-Origin为通配符*

#若是客户端传递cookie进入,需要设置允许证书等
        self.set_header(Access-Control-Allow-Credentials,"true")

完整代码

    #复杂请求
    def options(self, *args, **kwargs):#第一次用于预检
        #先允许网站接入
        #self.set_header(Access-Control-Allow-Origin,"*")  # 或者加上*代表所有的都允许
        #如果客户端允许传递cookie,那么这里请求头就不能是*,必须是指定的url
        self.set_header(Access-Control-Allow-Origin, "http://www.py_test1.com:8080")
        #若是请求方法不满足get,post
        self.set_header(Access-Control-Allow-Methods,"PUT,DELETE")#还可以添加其他,比如DELETE,不能是*
        #若是请求头也不满足简单请求,也需要设置
        self.set_header(Access-Control-Allow-Headers, "k1,k2")#客户端自定义请求头
        #若是客户端传递cookie进入,需要设置允许证书等
        self.set_header(Access-Control-Allow-Credentials,"true")
        #可以设置缓存时间,原来需要一次预检一次请求,现在只需要一次请求
        self.set_header(Access-Control-Max-Age,10)#10秒内不再产生预检

在第二次请求中:可以设置cookie,并获取

    def put(self, *args, **kwargs):#第二次为请求
        #由于设置了cookie,所有这里不允许*
        #self.set_header(Access-Control-Allow-Origin, "*")
        self.set_header(Access-Control-Allow-Origin,"http://www.py_test1.com:8080")
        self.set_header(Access-Control-Allow-Credentials,"true")
        #为跨域站点设置cookie
        print(self.cookies)
        self.set_cookie(kk,21)
        self.write(put ok)

注意第二次请求也是需要设置Access-Control-Allow-Origin

而且由于cookie的添加需要设置Access-Control-Allow-Credentials

 

前端完整:

技术分享图片
<script>
    function CorsAjax(){
        $.ajax({
            url:http://www.py_test2.com:8081/cors,
            dataType:text,
            data:{},
            type:"post",
            success:function(data){
                console.log(data);
            }
        })
    }


    //复杂请求,会发送两个请求,一个options一个put
    function CorsAjax2(){
        $.ajax({
            url:http://www.py_test2.com:8081/cors,
            dataType:text,
            data:{},
            type:"put",
            headers:{k1:ddasf,"k2":fa},
            xhrFields:{withCredentials:true},//默认是不允许携带cookie和ssl证书等,需要设置,服务端也要相应设置
            success:function(data){
                console.log(data);
            }
        })
    }
View Code

服务端完整:

技术分享图片
class CorsHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.write({"status":1,"message":"get"})

    #简单请求
    def post(self, *args, **kwargs):
        self.set_header(Access-Control-Allow-Origin,"http://www.py_test1.com:8080,http://www.py_test1.com:8080")#或者加上*代表所有的都允许
        self.write({"status":1,"message":"post"})

    #复杂请求
    def options(self, *args, **kwargs):#第一次用于预检
        #先允许网站接入
        #self.set_header(Access-Control-Allow-Origin,"*")  # 或者加上*代表所有的都允许
        #如果客户端允许传递cookie,那么这里请求头就不能是*,必须是指定的url
        self.set_header(Access-Control-Allow-Origin, "http://www.py_test1.com:8080")
        #若是请求方法不满足get,post
        self.set_header(Access-Control-Allow-Methods,"PUT,DELETE")#还可以添加其他,比如DELETE,不能是*
        #若是请求头也不满足简单请求,也需要设置
        self.set_header(Access-Control-Allow-Headers, "k1,k2")#客户端自定义请求头
        #若是客户端传递cookie进入,需要设置允许证书等
        self.set_header(Access-Control-Allow-Credentials,"true")
        #可以设置缓存时间,原来需要一次预检一次请求,现在只需要一次请求
        self.set_header(Access-Control-Max-Age,10)#10秒内不再产生预检

    def put(self, *args, **kwargs):#第二次为请求
        #服务端自定义响应头
        #self.set_header(xxoo,seven)
        #self.set_header(bili,daobidao)#这样是客户端无法接收
        #还需要设置一条
        #self.set_header(Access-Control-Expose-Headers,"xxoo,bili")

        #由于设置了cookie,所有这里不允许*
        #self.set_header(Access-Control-Allow-Origin, "*")
        self.set_header(Access-Control-Allow-Origin,"http://www.py_test1.com:8080")
        self.set_header(Access-Control-Allow-Credentials,"true")
        #为跨域站点设置cookie
        print(self.cookies)
        self.set_cookie(kk,21)
        self.write(put ok)
View Code

更多信息来源可以看此处

 

简单请求 OR 非简单请求

1
2
3
4
5
6
7
8
9
10
11
12
13
条件:
    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
 
注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求

ajax跨域原理(2) cors跨域资源共享

标签:若是   content   tar   第一次用   tornado   sed   console   color   url   

原文地址:https://www.cnblogs.com/ssyfj/p/8536011.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!