Django - Cross Domain Request (jsonp)

Keywords: Python JSON JQuery Django

Homology Policy

If both pages have the same protocol, port (if specified) and domain name, then both pages have the same source.

 

Example: Two Django demo s

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">click</button>

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

Start your browser, visit http://127.0.0.1:8001/demo2, click the button, and the console will error

Why did an error occur?Because the homology policy restricts ajax requests from being sent across domains.

We use script tag to introduce cdn without error, so try to solve the problem with script.

Modify demo.html

<body>
<button id="btn">click</button>

<script src="http://127.0.0.1:8002/demo1"></script>

</body>

Refresh Browser

Say Demo1 is undefined, then define a demo1; modify demo.html

<body>
<button id="btn">click</button>

<script>
var demo1 = "demo1"
</script>
<script src="http://127.0.0.1:8002/demo1/"></script>


</script>
</body>

And then make no mistake.

That's defining a demo1 function to see the effect; modify demo.html

<body>
<button id="btn">click</button>

<script>
    function demo1(){
        console.log("demo1")
    }

</script>
<script src="http://127.0.0.1:8002/demo1/"></script>


</body>

Modify view.py for demo1

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

 

nice, you can already execute the function.So add parameters to the function to see what happens.

Modify demo.html

<body>
<button id="btn">click</button>

<script>
    function demo1(ret){
        console.log(ret)
    }

</script>
<script src="http://127.0.0.1:8002/demo1/"></script>

</body>

Modify view.py for demo1

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

Refresh the browser to see the effect.

 

This is a simple implementation of JSONP, or the prototype of JSONP: create a callback function, then call it on a remote service and pass the JSON data as a parameter to complete the callback.

Filling JSON data into callback functions is what JSON+Padding for JSONP means.

 

Data acquisition is achieved by js dynamically creating script tags.

Modify demo.html

<body>
<button id="btn">click</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>

At this point, you can dynamically insert a script tag on the page through a button, and then get the data from the back end.

 

To make callbacks more flexible, we can pass the function name of the client-defined callback function to the server, which will return the callback function name and pass in the json data obtained to the function to complete the callback.

Modify demo.html

<body>
<button id="btn">click</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>

Modify views.py in demo1

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

A dynamic call is now implemented.

 

However, there are specific ways to implement jsonp in jQuery.

Modify demo.html

<body>
<button id="btn">click</button>

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

Note that there must be a callback parameter after the url so that the getJSON method knows to access the service in JSONP mode, the one after the callback?Is a callback function name automatically generated inside jQuery.

 

But what if we want to specify the callback function name ourselves, or persuade ourselves to specify the callback function name?We can do this using the $.ajax method:

Modify demo.html

<body>
<button id="btn">click</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>

Posted by Barkord on Sun, 19 May 2019 17:53:41 -0700