欢迎来到夜的世界

莫听穿林打叶声,何妨吟啸且徐行。竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生.料峭春风吹酒醒,微冷,山头斜照却相迎。回首向来萧瑟处,归去,也无风雨也无晴。
扩大
缩小

前端JSONPJIE解决跨域问题

       解决同源策略的两个方法       

   1 . JSONP   

   jsonp (将 JSON 数据填充进回调函数,这就是JSONP的JSON+Padding 的含义)

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

   思考 : 这算怎么回事 ? 

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

 借助 script 标签,实现跨域请求,示例 : 

所以只是单纯的返回一个也没有什么意义,我们需要的是数据

如下 : 可以返回一个字典,不过也可以返回其他的,(简单的解决了跨域,利用script)

项目一 : 

<body>
<h1>项目一</h1>
<button class="send_jsonp">jsonp</button>
<script>
    $(".send_jsonp").click(function () {
        $.ajax({
            url:"",
            success:function (data) {
                console.log(data)
            }
        })
    });

    function func(arg) {
        console.log(arg)
    }
</script>
<script src="http://127.0.0.1:8080/ajax_send2/"></script>
</body>

 项目二 : 

def ajax_send2(request):
    import json
    print(222222)
    # return HttpResponse("func('name')")
    s = {"name":"haiyan","age":12}
    # return HttpResponse("func('name')")
    return HttpResponse("func('%s')"%json.dumps(s))   #返回一个func()字符串,正好自己的ajax里面有个func函数,就去执行func函数了,
                                arg就是传的形参

 这样就取到值了 : 

  这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

  将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。

  但是以上的方式也有不足,回调函数的名字和返回的那个名字的一致。并且一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了。

  解决办法:javascript动态的创建script标签

===========================jQuery实现=====================
{#    创建一个script标签,让他请求一次,请求完了删除他#}
    //动态生成一个script标签,直接可以定义个函数,放在函数里面
    function add_script(url) {
        var ele_script = $("<script>");
        ele_script.attr("src",url);
        ele_script.attr("id","script");
        $("body").append(ele_script);
        $("#script").remove()
    }
    $(".kuayu").click(function () {
       add_script("http://127.0.0.1:8080/ajax_send2/")
    });


</script>



==================js实现==========================
<button onclick="f()">sendAjax</button>

<script>
    function addScriptTag(src){
         var script = document.createElement('script');
         script.setAttribute("type","text/javascript");
         script.src = src;
         document.body.appendChild(script);
         document.body.removeChild(script);
    }


    function func(name){
        alert("hello"+name)
    }

    function f(){
         addScriptTag("http://127.0.0.1:7766/SendAjax/")
    }
</script>

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

function f(){
         addScriptTag("http://127.0.0.1:7766/SendAjax/?callbacks=func")
    }

 将视图views改为

def SendAjax(request):
 
    import json
 
    dic={"k1":"v1"}
 
    print("callbacks:",request.GET.get("callbacks"))   
    callbacks=request.GET.get("callbacks")   #注意要在服务端得到回调函数名的名字
 
    return HttpResponse("%s('%s')"%(callbacks,json.dumps(dic)))

 

    2 . 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>

 

8002的views不改动。

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

      此外,如果说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现

 $.ajax

<script>

    function f(){
          $.ajax({
                url:"http://127.0.0.1:7766/SendAjax/",
                dataType:"jsonp",    
                jsonp: 'callbacks',   #键
          jsonpCallback:"SayHi" #函数的名字
 }); } function SayHi(arg){ alert(arg); } </script>

8002的views不改动。

当然,最简单的形式还是通过回调函数来处理:

<script>

    function f(){

            $.ajax({
               url:"http://127.0.0.1:7766/SendAjax/",
               dataType:"jsonp",            //必须有,告诉server,这次访问要的是一个jsonp的结果。
               jsonp: 'callbacks',          //jQuery帮助随机生成的:callbacks="wner"
               success:function(data){
                   alert("hi "+data)
              }
         });

       }

</script>

  jsonp: 'callbacks'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名'SayHi',server端接受callback键对应值后就可以在其中填充数据打包返回了; 

jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,那前端就得用回调函数来处理对应数据了。利用jQuery可以很方便的实现JSONP来进行跨域访问。  

注意 JSONP一定是GET请求

      3 . 应用    

 // 跨域请求实例
    $(".jiangxiTV").click(function () {

        $.ajax({
            url:"http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403",
             dataType: 'jsonp',
             jsonp: 'callback',
             jsonpCallback: 'list',
             success:function (data) {
                 console.log(data.data);   //  [{},{},{},{},{},{}]
                 week_list=data.data;
                 
                 $.each(week_list,function (i,j) {
                     console.log(i,j);  // 1 {week: "周一", list: Array(19)}
                     s="<p>"+j.week+"列表</p>";
                     $(".show_list").append(s);

                     $.each(j.list,function (k,v) {  // {time: "0030", name: "通宵剧场六集连播", link: "http://www.jxntv.cn/live/jxtv2.shtml"}
                          a="<p><a href='"+v.link+"'>"+v.name+"</a></p>";
                          $(".show_list").append(a);
                     })
                 })
                 
             }
        })


    })

 

posted on 2018-12-23 17:58  二十四桥_明月夜  阅读(562)  评论(0编辑  收藏  举报

导航