跨域訪問 jsonp

爲何須要jsonpjavascript

  同源策略阻止從一個域上加載的腳本獲取或操做另外一個域上的文檔屬性。也就是說,受到請求的 URL 的域必須與當前 Web 頁面的域相同。這意味着瀏覽器隔離來自不一樣源的內容,以防止它們之間的操做。java

  其實說白了就是腳本不支持跨域訪問ajax

那怎麼辦json

  一:是讓 Web 頁面向它源自的 Web 服務器請求數據,而且讓 Web 服務器像代理同樣將請求轉發給真正的第三方服務器。儘管該技術得到了廣泛使用,但它是不可伸縮的。另外一種方式是使用框架要素在當前 Web 頁面中建立新區域,而且使用 GET 請求獲取任何第三方資源。不過,獲取資源後,框架中的內容會受到同源策略的限制。跨域

  二:更理想方法是在 Web 頁面中插入動態腳本元素,該頁面源指向其餘域中的服務 URL 而且在自身腳本中獲取數據。腳本加載時它開始執行。該方法是可行的,由於同源策略不阻止動態腳本插入,而且將腳本看做是從提供 Web 頁面的域上加載的。但若是該腳本嘗試從另外一個域上加載文檔,就不會成功。幸運的是,經過添加 JavaScript Object Notation (JSON) 能夠改進該技術。瀏覽器

  JSONP(JSON with Padding)是一個非官方的協議,它容許在服務器端集成Script tags返回至客戶端,經過javascript callback的形式實現跨域訪問(這僅僅是JSONP簡單的實現形式)。緩存

  其原理很簡單,客戶端生成一方法,並將其名稱發到服務器,服務器返回  該方法調用的標籤,並將數據傳入進去。 相似於<script>CallBack({ 這裏是數據 })</script> 這樣的信息。安全

  並且使用上強大的Jquery的時候會更簡單,你會發現跟普通的ajax請求沒太大區別。服務器

  

  實例:框架

  這是以前單點登陸使用到的jsonp,這裏直接把它貼出來了。

    function Login() {
        $.ajax({
            type: "GET",
            url: "http://sso.tiexue.net/account/jsonlogon",
            data: "Username=" + $("#UserName").val() + "&Password=" + $("#Password").val() + "&ValidityDays=7&returnUrl=" + document.referrer,
            dataType: "jsonp",
            success: function (res) {
                if (res) {
                    if (res.success && res.success == true) {
                        if (res.returnurl && res.returnurl != "") {
                            window.location.href = returnValue;
                        } else {
                            window.location.href = "http://m.junph.com";
                        }
                    } else if (res && res.errors && res.errors != "") {
                        $("#loginInfo").text(res.errors).show();
                    }
                }
            }
        });
    }

  經過監控咱們能夠獲得這麼個東西,具體的監控信息我就不貼出來,畢竟是公司內信息。negotiate.js個js文件,讓咱們來看看內容吧

  jQuery18207690677059322467_1404976763158({"Url":"/797157b224e24e9da8e930644e22a645/arterySignalR","ConnectionToken":"AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAK6HmM0P+Q0+HxWeY1Eej1AAAAAACAAAAAAADZgAAwAAAABAAAAD4lgvnJP5Dq69Xhj31ctt7AAAAAASAAACgAAAAEAAAACqgv7fLBf+Vh5/dflOwOgMoAAAAW/5dV31Tn83EFf+n8c+QpdOAfTSmuepOHJ0VoLLwwe3hK72D07TwrBQAAACUMlWyaz8To7zTZgNK7lzw4Wf+Sg==","ConnectionId":"edf3a7f4-ad3f-4597-8dcd-1fbbe16c4304","KeepAliveTimeout":4.0,"DisconnectTimeout":6.0,"TryWebSockets":false,"ProtocolVersion":"1.3","TransportConnectTimeout":5.0});

  很簡單的一個方法調用,參數就是服務器端的json數據。

  方法名爲jsonp請求指定一個回調函數名。這個值將用來取代jQuery自動生成的隨機函數名。這主要用來讓jQuery生成度獨特的函數名,這樣管理請求更容易,也能方便地提供回調函數和錯誤處理。你也能夠在想讓瀏覽器緩存GET請求的時候,指定這個回調函數名。 

 

 

使用JSON的優勢在於:

  • 比XML輕了不少,沒有那麼多冗餘的東西。
  • JSON也是具備很好的可讀性的,可是一般返回的都是壓縮事後的。不像XML這樣的瀏覽器能夠直接顯示,瀏覽器對於JSON的格式化的顯示就須要藉助一些插件了。
  • 在JavaScript中處理JSON很簡單。
  • 其餘語言例如PHP對於JSON的支持也不錯。

JSON也有一些劣勢:

  • JSON在服務端語言的支持不像XML那麼普遍,不過JSON.org上提供不少語言的庫。
  • 若是你使用eval()來解析的話,會容易出現安全問題。

儘管如此,JSON的優勢仍是很明顯的。他是Ajax數據交互的很理想的數據格式。

JSONP 是構建 mashup 的強大技術,但不幸的是,它並非全部跨域通訊需求的萬靈藥。它有一些缺陷,在提交開發資源以前必須認真考慮它們。

第一,也是最重要的一點,沒有關於 JSONP 調用的錯誤處理。若是動態腳本插入有效,就執行調用;若是無效,就靜默失敗。失敗是沒有任何提示的。

例如,不能從服務器捕捉到 404 錯誤,也不能取消或從新開始請求。不過,等待一段時間尚未響應的話,就不用理它了。(將來的 jQuery 版本可能有終止 JSONP 請求的特性)。

 

JSONP 的另外一個主要缺陷是被不信任的服務使用時會很危險。由於 JSONP 服務返回打包在函數調用中的 JSON 響應,而函數調用是由瀏覽器執行的,

這使宿主 Web 應用程序更容易受到各種攻擊。若是打算使用 JSONP 服務,瞭解它能形成的威脅很是重要。

相關文章
相關標籤/搜索