• Django—跨域请求(jsonp)


    同源策略

    如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。

    示例:两个Django demo

    demo1

    url.py

    url(r'^demo1/',demo1),

    view.py

    def demo1(request):
        return HttpResponse("demo1")

    demo2

    url.py

    url(r'demo2$',demo2),

    view.py

    def demo2(request):
        return render(request,'demo.html')

    demo.html

    <body>
    <button id="btn">点击</button>
    
    <script>
        $("#btn").click(function () {
            $.ajax({
                url:"http://127.0.0.1:8002/demo1/",
                type:"get",
            }).done(function (data) {
                console.log(data)
            })
        });
    </script>
    </body>
    View Code

    启动浏览器,访问http://127.0.0.1:8001/demo2,点击按钮,然后控制台报错

    为什么报错?因为同源策略限制跨域发送ajax请求。

    我们用script标签引入cdn没有报错,so,用script解决问题试试。

    修改demo.html

    <body>
    <button id="btn">点击</button>
    
    <script src="http://127.0.0.1:8002/demo1"></script>
    
    </body>
    View Code

    刷新浏览器

    说demo1未定义,那定义一个demo1;修改demo.html

    <body>
    <button id="btn">点击</button>
    
    <script>
    var demo1 = "demo1"
    </script>
    <script src="http://127.0.0.1:8002/demo1/"></script>
    
    
    </script>
    </body>
    View Code

     然后不报错了。

     那在定义一个demo1函数,看看效果;修改demo.html

    <body>
    <button id="btn">点击</button>
    
    <script>
        function demo1(){
            console.log("demo1")
        }
    
    </script>
    <script src="http://127.0.0.1:8002/demo1/"></script>
    
    
    </body>
    View Code

    修改demo1的view.py 

    def demo1(request):
        return HttpResponse("demo1()")

     

    nice,已经能执行函数了。那给函数加参数看看效果。

     修改demo.html

    <body>
    <button id="btn">点击</button>
    
    <script>
        function demo1(ret){
            console.log(ret)
        }
    
    </script>
    <script src="http://127.0.0.1:8002/demo1/"></script>
    
    </body>
    View Code

    修改demo1的view.py

    import json
    def demo1(request):
        ret = {"status": 1, "msg": "demo1"}
        return HttpResponse("demo1({})".format(json.dumps(ret)))
    View Code

     刷新浏览器看效果。

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

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

     

    通过js动态的创建script标签来实现数据的获取。

     修改demo.html

    <body>
    <button id="btn">点击</button>
    
    <script>
        function demo1(ret){
            console.log(ret)
        }
    
        function addScriptTag(src) {
            var sTag = document.createElement("script");
            $(sTag).attr("src", src);
            $("body").append(sTag);
            $(sTag).remove();
        }
    
    </script>
    
    <script>
        $("#btn").click(function () {
            addScriptTag("http://127.0.0.1:8002/demo1/")
        })
    </script>
    </body>
    View Code

    此时通过按钮就可以动态的在页面上插入一个script标签,然后从后端获取数据。

    为了实现更加灵活的调用,我们可以把客户端定义的回调函数的函数名传给服务端,服务端则会返回以该回调函数名,将获取的json数据传入这个函数完成回调。

     修改demo.html

    <body>
    <button id="btn">点击</button>
    
    <script>
        function demo1(ret){
            console.log(ret)
        }
    
        function addScriptTag(src) {
            var sTag = document.createElement("script");
            $(sTag).attr("src", src);
            $("body").append(sTag);
            $(sTag).remove();
        }
    
    </script>
    
    <script>
        $("#btn").click(function () {
            addScriptTag("http://127.0.0.1:8002/demo1/?callback=demo1")
        })
    </script>
    </body>
    View Code

    修改demo1中的views.py

    import json
    def demo1(request):
        ret = {"status": 1, "msg": "demo1"}
        func_name = request.GET.get("callback")
        return HttpResponse("{}({})".format(func_name, json.dumps(ret)))
    View Code

    此时实现动态的调用了。

    然而jQuery中有专门的方法实现jsonp。

    修改demo.html

    <body>
    <button id="btn">点击</button>
    
    <script>
        $("#btn").click(function () {
            $.getJSON("http://127.0.0.1:8002/demo1/?callback=?",function (data) {
                console.log(data)
            })
        })
    </script>
    View Code

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

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

    修改demo.html

    <body>
    <button id="btn">点击</button>
    
    <script>
        $("#btn").click(function () {
            $.ajax({
                url:"http://127.0.0.1:8002/demo1/",
                dataType:"jsonp",
                jsonp:"callback",
                jsonpCallback:"demo1"
            }).done(function (data) {
                console.log(data)
            })
        });
    </script>
    </body>
    View Code

     

  • 相关阅读:
    Smart Client Architecture and Design Guide
    Duwamish密码分析篇, Part 3
    庆贺发文100篇
    .Net Distributed Application Design Guide
    New Introduction to ASP.NET 2.0 Web Parts Framework
    SPS toplevel Site Collection Administrators and Owners
    来自Ingo Rammer先生的Email关于《Advanced .Net Remoting》
    The newsletter published by Ingo Rammer
    深度探索.Net Remoting基础架构
    信道、接收器、接收链和信道接受提供程序
  • 原文地址:https://www.cnblogs.com/ForT/p/10739150.html
Copyright © 2020-2023  润新知