JS跨域請求(script標籤)和JQuery跨域請求(jsonp)

前言:javascript

爲儘量保證瀏覽器端安全,瀏覽器會遵循SOP協議,即同源協議php

ajax沒法完成跨域請求html

$.get $.post $.ajax都不能夠前端

jsonp做爲ajax的一種擴展協議能夠完成跨域請求java

$.getJson()也能夠完成跨域請求(固然不跨域也能夠)jquery

平常開發中會常常遇到前端跨域訪問請求數據的場景ajax

好比json

www.server.com 
img.server.com

當用戶在www下瀏覽時須要獲取指定記錄id的圖片,則咱們須要在www的域下請求img域下的數據,常規狀況下瀏覽器會處於安全控制限制沒法完成跨域請求,但頁面中的script或iframe標籤是能夠載入跨域請求的(link img也能夠)後端

實現方式:跨域

===============================================================

服務端

看網上不少講跨域的都只是說了下前端如何編碼,對後端的處理隻字未提,雖而後端的處理很簡單,但後端的處理纔是點睛之筆,返回一個前端的調用函數語句,這就是傳說中的回調函數

<?php
    if (isset($_GET['callback'])) {
        $callback = $_GET['callback'];
        $resultArr = [];
        $resultArr['id'] = $_GET['id'];
        $resultArr['img'] = "http://img.server.com/upload/img/201511031319.png";
        $resultJson = json_encode($resultArr);
        //callback({id:1, img:....}) 組裝成調用js函數的格式 客戶端載入天然觸發其本地定義的回調函數
        echo $callback . "({$resultJson})";
        exit();     
    } //由於是被script標籤請求載入的,因此返回的數據會包在script中,天然就觸發了callback函數

===============================================================

一、JS script方式

其實原理很簡單

一、在當前域下我定義一個函數做爲回調函數

二、組建一個script標籤元素節點,設置src爲跨域請求的某API的url地址,同時此url地址中務必填寫上回調函數名參數

三、將script標籤掛載到文檔流中,會跨域請求載入,變相的訪問了跨域API,觸發了API的方法,返回的數據被填充到script標籤中,若是返回的是一個當前域下定義好的函數,那天然就觸發處理相關數據了

四、跨域完成

在www下定義回調函數callback

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript" src="http://www.yii.com/a.js"></script>
</head>
<body>
<button onclick="request()">click here</button>
    <script type="text/javascript">
    //回調函數callback定義
    //服務端輸出的數據爲 callback({key1:data1, key2;data2}) 到本頁面 即調用此定義好的函數
    function callback(json) {
        for (i in json) {
            alert(i + ":" + json[i]);
        }
        if (json.tagId) {
            var tagId = document.getElementById(json.tagId);
            tagId.parentNode.removeChild(tagId);
        }
    }
    //發起跨域請求
    function request() {
        //利用script標籤可跨域訪問的特性
        var script = document.createElement('script');
        script.id = Math.random();
        script.type = 'text/javascript';
        //跨域 將callback函數名稱傳遞給跨域服務器 服務端利用此函數名組建
        script.src = "http://img.server.com/index.php?callback=callback&id=1&tagId=" + script.id;
        //將可跨域請求的script標籤掛載到head標籤上
        document.getElementsByTagName("head")[0].appendChild(script);
    }
    </script>
</body>
</html>

 

===============================================================

二、jsonp方式

jsonp是ajax的擴展,嚴格的說它已經不是ajax,只是複用ajax的某些控制流程,封裝咱們上面說的js方式

重點:

dataType:'jsonp' //指定使用jsonp方式

jsonp:'callback' //回調函數的鍵名 傳遞給服務器時服務器經過此鍵名獲取應該返回調用的函數名

jsonpCallback:'myCallback' //回調函數名不隨機,自定義一個

<script type="text/javascript" >
    //其實jquery會組合成這樣的請求
    //http://img.server.com/index.php?callback=myCallback&id=1
    $.ajax({
        async: false,
        type: 'get',
        url: "http://img.server.com/index.php?id=1",
        //指定爲jsonp方式
        dataType: 'jsonp',
        //回調函數的鍵值名,即服務端經過此鍵值訪問傳遞的回調函數名
        jsonp: 'callback',
        //回調函數名,若不指定則jquery會隨機生成一個
        jsonpCallback: 'myCallback',
        success: function(result) {
            for (var i in result) {
                alert(i + ":" + result[i]);
            }
        },
        timeout: 3000
    });
    //Jquery會根據你指定的jsonpCallback參數在本地生成一個
    //function myCallback(result) {
        //這樣就調用了success方法
        //this.success(result);
    //} 
</script>

===============================================================

三、getJSON

重點:

必定要在url中寫上callback=?,只有這樣纔會在本地生成一個回調函數,跨域的後端經過callback獲取到此函數名,進行回調

<script type="text/javascript" >
    //其實jquery會組合成這樣的請求
    //http://img.server.com/index.php?callback=myCallback&id=1
    var url = "http://img.server.com/index.php?callback=?"; //記住必定要有callback=?
    var data = {'id':1};
    $.getJSON(
        url,
        data,
        function(result){
            for (var i in result) {
                alert(i + ":" + result[i]);
            }
        });
</script>

===============================================================

相關文章
相關標籤/搜索