Jsonp跨域

Jsonp -- JSON+Padding

JS对JSONP的实现

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

​ script标签的src属性是可以直接实现跨域的,这是标签特性,所以我们可以借助它来实现跨域。

简单实现:

index.html

<button>ajax</button>
{% csrf_token %}

<script>
    function func(name){ //func写在src请求的上面,不然找不到这个func函数,我们请求的另一个网站的后端,返回的数据就是这个函数名称加参数的形式  // # HttpResponse("func('xx')")
        alert(name)
    }
</script>

<script src="http://127.0.0.1:8000/SendAjax/"></script>

flask

from django.views.decorators.csrf import csrf_exempt
import json

@csrf_exempt  #如果跨域请求是post请求,别忘了csrftoken可能会产生的阻拦,get请求不需要加上它
def SendAjax(request):

    # dic={"k1":"v1"}
    return HttpResponse("func('xx')")  # return HttpResponse("func('%s')"%json.dumps(dic))
# 注意,func这个名称是另外那个发送请求的网站的一个js代码函数名称

JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

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

进阶版:

<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:8002/SendAjax/?callbacks=func") // callbacks这个名称不是固定的,和另一个网站的服务端商量好就行了,就是后端取值时的一个参数而已
    }
</script>

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)))

jQuery对JSONP的实现

getJSON

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

html:

<button onclick="f()">sendAjax</button>

<script>

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

注意的是在url的后面必须添加一个callbacks(callbacks名不是固定的)参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callbacks后面的那个问号是内部自动生成的一个回调函数名

$.ajax

如果想指定自己的回调函数名,或者说服务上规定了固定回调函数名,可以使用$.ajax方法来实现。

<script>

    function f(){
          $.ajax({  //type请求方法没写,默认是get请求
                url:"http://127.0.0.1:8000/SendAjax/",
                dataType:"jsonp",
                jsonp: 'callbacks',
                jsonpCallback:"SayHi"
           });

       }

    function SayHi(arg){
                alert(arg.k1);  //k1是后端返回的数据中的键值对的键
            }

</script>

或者通过回调函数处理:较简单

<script>

    function f(){

            $.ajax({
               url:"http://127.0.0.1:8002/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请求

应用:

<input type="button" onclick="AjaxRequest()" value="跨域Ajax"/>


<div id="container"></div>


    <script type="text/javascript">
        function AjaxRequest() {
            $.ajax({
                url: 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403',
                type: 'GET',
                dataType: 'jsonp',
                jsonp: 'callback',
                jsonpCallback: 'list',
                success: function (data) {
                    
                    $.each(data.data,function(i){
                        var item = data.data[i];
                        var str = "<p>"+ item.week +"</p>";
                        $('#container').append(str);
                        $.each(item.list,function(j){
                            var temp = "<a href='" + item.list[j].link +"'>" + item.list[j].name +" </a><br/>";
                            $('#container').append(temp);
                        });
                        $('#container').append("<hr/>");
                    })

                }
            });
        }
</script>
posted @ 2020-08-27 14:00  SensorError  阅读(135)  评论(0编辑  收藏  举报