跨域

同源策略 Jsonp

同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

 

何为同源:

  协议,域名,端口都相同

  如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

Cors

参考博客:http://blog.csdn.net/u014344668/article/details/54948546

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。
浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。 因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

cors 两种请求: 简单请求与 预先请求

简单请求:
当请求同时满足下面两个条件时,浏览器会直接发送GET请求,在同一个请求中做跨域权限的验证。
请求方法是下列之一:
GET
HEAD
POST
请求头中的Content-Type请求头的值是下列之一:
application/x-www-form-urlencoded
multipart/form-data
text/plain

############

预先请求
当请求满足下面任意一个条件时,浏览器会先发送一个OPTION请求,用来与目标域名服务器协商决定是否可以发送实际的跨域请求。
请求方法不是下列之一:
GET
HEAD
POST
请求头中的Content-Type请求头的值不是下列之一:
application/x-www-form-urlencoded
multipart/form-data
text/plain

浏览器在发现页面中有上述条件的动态跨域请求的时候,并不会立即执行对应的请求代码,而是会先发送Preflighted requests(预先验证请求),Preflighted requests是一个OPTION请求,用于询问要被跨域访问的服务器,是否允许当前域名下的页面发送跨域的请求。

OPTIONS请求头部中会包含以下头部:Origin、Access-Control-Request-Method、Access-Control-Request-Headers。
服务器收到OPTIONS请求后,设置Access-Control-Allow-Origin、Access-Control-Allow-Method、Access-Control-Allow-Headers头部与浏览器沟通来判断是否允许这个请求。
如果Preflighted requests验证通过,浏览器才会发送真正的跨域请求。

 

Jsonp

  jsonp是json用来跨域的一个东西。原理是通过script标签的跨域特性来绕过同源策略。

<script src="http://code.jquery.com/jquery-latest.js"></script>

自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调:

#客户端
<button class="send_ajax">send_ajax</button>

<script>
    //点击编写事件
    $(".send_ajax").click(function () {

       kuayu_request("http://127.0.0.1:8000/send_ajax/?callback=bar")   //自己组建的回调函数名为bar

    });
    //自己组建跨域的<script>标签
    function kuayu_request(url) {
        var $script=$("<script>");  // 创建script标签,是一个jquery对象: <script>
        $script.attr("src",url);
        $("body").append($script);
        $("body script:last").remove();
    }
    //回调函数
    function bar(arg) {
       console.log(arg);
       console.log(JSON.parse(arg));
    }

</script>
客户端

 

def send_ajax(request):

 

    import json

 

    dic={"k1":"v1"}

 

    print("callback:",request.GET.get("callback"))

    callbacks=request.GET.get("callback")

 

    return HttpResponse("%s('%s')"%(callbacks,json.dumps(dic)))
服务端

 

jQuery对JSONP的实现

getJSON

jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法

#客户端
<button onclick="f()">sendAjax</button>

<script>

    function f(){
          $.getJSON("http://127.0.0.1:7766/SendAjax/?callbacks=?",function(arg){
            alert("hello"+arg)
        });
    }
    
</script>

#fuwuduan 不改动。
结果是一样的,要注意的是在url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个问号是内部自动生成的一个回调函数名。
getJSON方法

 $.ajax

<script>

    $(".send_ajax").click(function () {

        $.ajax({
            url:"http://127.0.0.1:8000/send_ajax/",
            dataType:"jsonp",   // 跨域请求  <script>
            jsonp: 'callbacks',   //拼接回调函数,callbacks为键
         jsonpCallback:"SayHi"  //回调函数的函数名,SayHi为值
        })


    });

    function SayHi(arg) {      //回调函数
        console.log("hello",arg)
    }
</script>
方式一:规定好的回调函数名

 

import json
def send_ajax(request):
    func_name=request.GET.get("callbacks")
    print("========",func_name)                              #jQuery32108857898425508359_1515120720532
    s = {"name": "egon", "age": 122}
    return HttpResponse("%s('%s')"%(func_name,json.dumps(s)))
方式一的服务端

 

<script>

    $(".send_ajax").click(function () {

        $.ajax({
            url:"http://127.0.0.1:8000/send_ajax/",
            dataType:"jsonp",   // 跨域请求  <script>
            jsonp: 'callbacks',  //jQuery帮助随机生成的:callbacks="asdfadf1123141"
            success:function (data) {
                console.log(data)
            }
        })

    });


</script>
方式二:回调函数随机生成函数名
posted @ 2018-03-22 11:53  JAYWX  阅读(104)  评论(0编辑  收藏  举报