36)django-jsonp跨域

一:什么是JSONP

  JSONP(JSON with Padding)是JSON的一种"使用模式",可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

二:使用原生js,或者jquery访问跨域报错

    <body>
    <h1>后台获取结果</h1>
    {{ result }}
    <h1>js直接获取结果</h1>
    <input type="button" value="获取数据" id="ok_button" onclick="getData();">
    <div id=""container>

    </div>

    <script>
        //原生js
        function getData(){
            var xhr=new XMLHttpRequest()
            xhr.open("GET","http://127.0.0.1:8001/req")//以什么方式a
            xhr.onreadystatechange=function(){//执行成功后的回调信息
                console.log(xhr.responseText)
            }
            xhr.send() //发送信息
        }
    </script>
    </body>

    #js发错报错
    XMLHttpRequest cannot load http://127.0.0.1:8001/req. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. 
    以把请求放过去了,也收到了,但在在数据回到浏览器的时候,我浏览器拒不接受。这是浏览器策略。
View Code

三:使用script发送数据

#jsonp 存在的意义就是:由于浏览器具有同源策略(阻止ajax请求,但是无法阻止script)。
    #通过script发送数据。
    <body>
        <h1>后台获取结果</h1>
        {{ result }}
        <h1>js直接获取结果</h1>
        <input type="button" value="获取数据" id="ok_button" onclick="getData();">
        <div id=""container>
    
        </div>
    
        <script>
            //原生js
            function getData(){    
                var tag=document.createElement("script") //创建script标签
                tag.src="http://127.0.0.1:8001/req //要发送地址
                document.head.appendChild(tag)//script加入头部
            }
        </script>
    </body>
    #但是返回结果会出错,原因返回的结果不是script语法,所以要把返回结果必须是JS格式
    return HttpResponse("alter(123)") 正确
    return HttpResponse("123")报错。

四:例子

#例子:通过script跨哉访问请求(js发送数据)
    工程2:
    #views.py
    from django.shortcuts import render,HttpResponse

    # Create your views here.
    def req(request):
        func=request.GET.get("func")
        return HttpResponse('func("XXX")') #返回func是js定义的函数

    #urls.py
    url(r'^req$',views.req),

    #起动地址
    http://127.0.0.1:8001/req


    工程1:
    #views.py
    from django.shortcuts import render,HttpResponse
    import requests
    # Create your views here.
    
    def a(request):
        return HttpResponse("ok")

    #urls.py
    #url(r'^a/', views.a),


    #模板
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>js直接获取结果</h1>
        <input type="button" value="获取数据" id="ok_button" onclick="getData();">
        <div id=""container>
    
        </div>
    
        <script>
            //原生js
            function getData(){
    
                var tag=document.createElement("script") //创建script标签
                tag.src="http://127.0.0.1:8001/req?func=func" //要发送地址
                document.head.appendChild(tag)//script加入头部
            }
            #func=func 把js方法传递给后台
            function func(arg){
                alert(arg);
            }
        </script>
    </body>
    </html>
View Code

五:JSONP跨域请求的本质

    由于浏览器具有同源策略(阻止ajax跨域请求,但是无法阻止script)
    1)创建script标签
    2)src=远程地址
    3)返回的数据必须是js格式

    JSONP只能发GET请求

六:jquery跨域实现

#jsonp跨域请求jquery方式
    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        //原生js

            $.ajax({
                url:"http://127.0.0.1:8001/req?",
                type:"POST",
                dataType:"jsonp",
                jsonp:"callback",//发送的参数
                jsonpCallback:"func",//发送参数的值 等价http://127.0.0.1:8001/req?callback=func
            })
             }
        function func(arg){
            alert(arg);
        }
    </script>

七:总结

  就是利用script标签绕过同源策略,获得一个类似这样的数据,jsonpcallback是页面存在的回调方法,参数就是想得到的json。

原文地址:https://www.cnblogs.com/lixiang1013/p/8011279.html