zoukankan      html  css  js  c++  java
  • django-jsonp同源策略

    一:jsonp同源策略:

    1.同源策略概念
    同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,
    浏览器只是针对同源策略的一种实现。 同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来
    百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,
    浏览器会在控制台中报一个异常,提示拒绝访问。
    ==================================http://127.0.0.1:8001项目的index
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="http://code.jquery.com/jquery-latest.js"></script>
    </head>
    <body>
    
    
    <button>ajax</button>
    {% csrf_token %}
    
    <script>
        $("button").click(function(){
    
    
            $.ajax({
                url:"http://127.0.0.1:7766/SendAjax/",
                type:"POST",
                data:{"username":"yuan","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},
                success:function(data){
                    alert(123);
                    alert(data)
                }
            })
        })
    </script>
    </body>
    </html>
    
    
    ==================================http://127.0.0.1:8001项目的views
    
    def index(request):
    
    
        return render(request,"index.html")
    
    
    def ajax(request):
        import json
        print(request.POST,"+++++++++++")
        return HttpResponse(json.dumps("hello"))
    示例-8001
    
    
    复制代码
    
    ==================================http://127.0.0.1:8002项目的index
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="http://code.jquery.com/jquery-latest.js"></script>
    </head>
    <body>
    
    
    <button>sendAjax</button>
    
    {% csrf_token %}
    
    <script>
        $("button").click(function(){
    
    
            $.ajax({
                url:"/SendAjax/",
                type:"POST",
                data:{"username":"yuan","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},
                success:function(data){
                    alert(data)
                }
            })
        })
    </script>
    
    </body>
    </html>
    
    
    ==================================http://127.0.0.1:8002项目的views
    
    def index(request):
    
        return render(request,"index.html")
    
    from django.views.decorators.csrf import csrf_exempt
    
    @csrf_exempt
    
    
    def SendAjax(request):
    
        import json
    
        print("++++++++")
    
        return HttpResponse(json.dumps("hello2"))
    示例-8002
    点击时,会发生错误, 当点击项目1的按钮时,发送了请求,但是会发现报错如下:
    已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:7766/SendAjax/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')。
    但是注意,项目2中的访问已经发生了,说明是浏览器对非同源请求返回的结果做了拦截。

    2,jsonp:其实就是JSON+Padding,json填充.

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

    # =============================http://127.0.0.1:8001/index
    
    
    <button>ajax</button>
    {% csrf_token %}
    
    <script>
        function func(name){
            alert(name)
        }
    </script>
    
    <script src="http://127.0.0.1:7766/SendAjax/"></script>   #这里通过src直接调用8002里面的函数,然后通过运行函数,获得返回值
                                      #最后通过function拿出里面的值. #这里要注意的是,当这样写的时候,最后调用的路径,一定要写在最后,不然会报错. # =============================http://127.0.0.1:8002/ from django.views.decorators.csrf import csrf_exempt @csrf_exempt def SendAjax(request): import json print("++++++++") # dic={"k1":"v1"} return HttpResponse("func('yuan')") # return HttpResponse("func('%s')"%json.dumps(dic) 这里通过return HttpResponse("func('yuan')"),返回给调用他函数,
     这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。
    将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义

    3,自己创建标签,灵活调用远程服务

    一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。
    我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了
    function addscripttag(net) {        //首先利用函数创建标签
            var script=document.createElement('script');   //创建script标签
            script.setAttribute('type','text/javascript');      
            script.src=net;                                 //再标签上加入src属性,调用路径
    
            document.body.appendChild(script);              //用body加上该标签
            document.body.removeChild(script)               //调用完以后消失,省空间
        }
    
    function callback(data) {                               //用来接收另一个浏览器数据
        console.log(data)                                   //接收到的数据放在这里处理
    }
    
    function f() {                                          //点击运行函数,把路径传过去
        addscripttag('http://127.0.0.1:8000/blog/jiangxitv/?callback=callback')
    }           
    
    
    为了更加灵活,现在将你自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调:
    function f(){
             addScriptTag("http://127.0.0.1:7766/SendAjax/?callbacks=func")
        }
    
    8001用get方法通过?+函数名的方法把函数名传过去.
    ---------------------------------------------
    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)))
    
    8002用过接收到函数名,可以找到函数名,并传
    
    

    4,jquery实现jsonp

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

    8001的html改为:

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

    8002的views不改动。

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

    2:) $.ajax实现 , 这里还需要

    注意 JSONP一定是GET请求.

    1,需要回调函数名

    <script>
        function f(){
              $.ajax({
                    url:"http://127.0.0.1:7766/SendAjax/", 
                    dataType:"jsonp",          #这里指定返回的格式是jsonp格式
                    jsonp: 'callbacks',    
                    jsonpCallback:"SayHi"    #这个是给另一个浏览器,传一个回调函数名.
               });
           }
        function SayHi(arg){
                    alert(arg);
                }
    </script>    
    jsonp: 'callbacks'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名'SayHi',server端接受callback键对应值后就可以在其中填充数据打包返回了; 

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

    
    

    2,不需要传送回调函数名.

    <script>
    
        function f(){
    
                $.ajax({
                   url:"http://127.0.0.1:7766/SendAjax/",
                   dataType:"jsonp",            //必须有,告诉server,这次访问要的是一个jsonp的结果。
                   jsonp: 'callbacks',          //jQuery帮助随机生成的:callbacks="wner"
                   success:function(data){      #这里不需要传函数名,直接接受,ajax随即产生一个函数名.
                       alert("hi "+data)
                  }
             });
           }
    </script>

    例子:
    <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>
    View Code
    
    
    





























  • 相关阅读:
    171 01 Android 零基础入门 03 Java常用工具类02 Java包装类 01 包装类简介 01 Java包装类内容简介
    170 01 Android 零基础入门 03 Java常用工具类01 Java异常 08 Java异常总结 01 异常总结
    169 01 Android 零基础入门 03 Java常用工具类01 Java异常 07 异常链 01 异常链简介
    168 01 Android 零基础入门 03 Java常用工具类01 Java异常 06 自定义异常 01 自定义异常类
    167 01 Android 零基础入门 03 Java常用工具类01 Java异常 05 使用throw和throws实现异常处理 02 使用throw抛出异常对象
    166 01 Android 零基础入门 03 Java常用工具类01 Java异常 05 使用throw和throws实现异常处理 01 使用throws声明异常类型
    165 01 Android 零基础入门 03 Java常用工具类01 Java异常 04 使用try…catch…finally实现异常处理 05 return关键字在异常处理中的使用
    DevExpress WPF v20.2版本亮点放送:全新升级的PDF Viewer
    界面控件DevExpress使用教程:Dashboard – 自定义导出
    DevExpress WinForms帮助文档:表单控件
  • 原文地址:https://www.cnblogs.com/52forjie/p/7930907.html
Copyright © 2011-2022 走看看