CORS

 CORS:

    概念:因为浏览器都有同源策略,为了解决跨域请求,有两种方式,1.JSONP 通过动态生成script的方式,在通过ajax发起请求并获取相应的数据

        2.使用CORS的方式,需要浏览器和服务器同时支持,目前所有的浏览器都支持该功能,整个CORS通讯过程都是浏览器自动完成,不需要用户参与,

        浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,因此实现CORS通讯的关键是服务器,只要服务器实现了CORS接口就可以跨域通讯。

    两种请求:

1.简单请求:

    请求方式:HEAD,GET,POST

    HTTP的头信息:

        .Accept

        .Accept-Language

        .Content-Language

扫描二维码关注公众号,回复: 99204 查看本文章

        .Last-Event-ID

        .Content-Type 只限于三种值:application/x-www-form-urlencoded,multipart/form-data,tecx/plain

    请求流程:

   浏览器发现这次跨源ajax是简单请求,就会自动在头信息上添加一个Origin字段,该字段用来说明本次请求来自哪一个源(协议+域名+端口),

   服务器根据这个值,决定是否同意这次请求,如果在许可范围内,服务器的响应,会多出几个头信息字段。

   1.Access-Control-Allow-Origin: http://api.bob.com  #这个字段必须的,*表示接受任何域名的请求

   2.Access-Control-Allow-Credentials: true #可选 表示是否可以发送Cookie

   3.Access-Control-Expose-Headers: FooBar #getResponseHeader()方法只能拿到6个基本字段之外的其他字段

   4.withCredentials:

       如果要把Cookie发送到服务器,一方面需要服务器同意Access-Control-Allow-Credentials: true,

       另一方面,开发者必须在Ajax请求中打开withCredentials属性   var xhr = new XMLHttpRequest();xhr.withCredentials = true

       如果需要发送cookie,Access-Control-Allow-Origin 不能设置为*

   A网站:

       <input type="button" value="获取用户数据" onclick="getUsers()">

       <script src="jquery-1.12.4.min.js"></script>

       <script>

           function getUsers() {

               $.ajax({

                   url: 'http://127.0.0.1:8000/users/',

                   type:'GET',

                   success:function (ret) {

                       console.log(ret)

                   }

               })

           }

       </script>

  

   服务商:

       class UsersView(views.APIView):

           def get(self,request,*args,**kwargs):

           ret = {

               'code':1000,

               'data':'陈太章'

           }

           response = JsonResponse(ret)

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

           return response

         

2.非简单请求:

    请求方式:PUT,DELETE

    头信息:Content-Type 字段的类型是application/json

    请求流程:

  1.在正式通信之前,增加一次HTTP查询请求,先询问服务器,当前网页所在的域名是否在服务器的许可名单中,以及是否可以使用头信息,只有得到许可后

      浏览器才会发出正式的XMLHttpRequest请求,预检请求的方法是option,表示这个请求是用来询问的,头信息里面的关键字origin表示来自于哪一个源

      还包含其他两个特殊的字段,1.Access-Control-Request-Method列出CORS请求会使用到那些方法,2.Access-Control-Request-Headers 列出额外发送的头信息。

  2.服务器收到预检后,检查各个字段确认允许跨源请求,就可以做出回应,如果服务器不同意预检请求,就会返回一个正常的HTTP回应,但是不包含CORS相关的头信息,

      浏览器就认定,服务器不同意预检,触发错误。

      服务器返回CORS相关的字段:

          1.Access-Control-Allow-Methods: GET, POST, PUT #表明服务器支持的所有跨域请求方法

          2.Access-Control-Allow-Headers: X-Custom-Header # 表明服务器支持的所有头信息字段

          3.Access-Control-Allow-Credentials: true #表明可以携带cookie

          4.Access-Control-Max-Age: 1728000 #表明预检的有效时间,在此期间,不用在发送另一次的预检

  3.服务器通过预检请求后,在预检的有效区内,每次的CORS请求都走简单请求方式。

          def options(self, request, *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)

              response = HttpResponse()

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

              response['Access-Control-Allow-Headers'] = 'h1'

              # response['Access-Control-Allow-Methods'] = 'PUT'

              return response

猜你喜欢

转载自www.cnblogs.com/mihon/p/8980915.html