Django—跨域請求(jsonp)

同源策略html

若是兩個頁面的協議,端口(若是有指定)和域名都相同,則兩個頁面具備相同的源。ajax

 

示例:兩個Django demojson

demo1後端

url.py跨域

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

view.py瀏覽器

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

 

demo2app

url.pyide

url(r'demo2$',demo2),

view.py函數

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

demo.htmljsonp

<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
相關文章
相關標籤/搜索