jsonp跨域請求學習筆記

前言

ajax,用蒼白的話讚賞:很好。php

咱們能夠使用ajax實現異步獲取數據,減小服務器運算時間,大大地改善用戶體驗;咱們能夠使用ajax實現小系統組合大系統;咱們還能夠使用ajax實現前端的優化。(好一個排比)html

雖然ajax很好,但在使用起來也會有必定的限制,出於安全考慮,不容許跨域通訊。若是嘗試從不一樣的域請求數據,會出現安全錯誤。(下面例子1能夠直觀看出)前端

同源策略限制

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

所謂同源是指,域名,協議,端口相同。ajax

平地一聲吼

本文講解的是怎麼利用ajax利用jsonp實現跨域請求,那麼知道「同源策略」,就能夠解決不少疑問:「爲毛個人ajax加載不了數據!」「爲毛瀏覽器控制檯會對我如此漂亮的代碼報錯!」json

例子1

先上一個錯誤示範跨域

客戶端代碼:瀏覽器

<script>
    // 客戶端使用getJSON方法請求另外一臺機子上的腳本
    $.getJSON("http://172.22.22.120/new/ajax.php",function(json){
        alert(json.website);
    });
</script>

服務端PHP腳本代碼:安全

<?php
    // ajax.php
    header('Content-type: application/json');

    echo json_encode(array('website'=>'hcoding'));
?>

firefox下的錯誤提示:服務器

ajax跨域請求錯誤提示

根據同源策略的概念,localhost和172.22.22.120是出於不一樣的域名下的,因此跨域請求理所固然地被瀏覽器拒絕了。

JSONP

JSONP(JSON with Padding)是資料格式 JSON 的一種「使用模式」,可讓網頁從別的網域要資料。另外一個解決這個問題的新方法是跨來源資源共享。因爲同源策略,通常來講位於 server1.example.com 的網頁沒法與不是 server1.example.com 的服務器溝通,而 HTML 的 <script> 元素是一個例外。利用 <script> 元素的這個開放策略,網頁能夠獲得從其餘來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並非 JSON,而是任意的 JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。——摘自維基百科

這話該怎麼理解呢!我我的是這樣認爲的,用<script>跨域的請求數據,跨域的服務器返回一段【JavaScript代碼】,是 的,你沒看錯,不是json格式數據,是JavaScript代碼,這樣,這段代碼就由JavaScript 直譯器執行。上例子更直觀:

例子2

客戶端代碼:

<script>
    // 這是回調方法
    function cb(data){
        alert(data.website);
    }
</script>
<!--這是跨域請求的代碼,切記,這段代碼要在回調函數以後-->
<script src="http://172.22.22.120/new/ajax_jsonp.php?callback=cb"></script>

服務端PHP腳本代碼:

<?php
    $cb = htmlspecialchars($_GET['callback']);  // 注意了,這裏要作好過濾,防止xss攻擊
    echo $cb,'(',json_encode(array('website'=>'hcoding')),')';  // 返回客戶端的數據爲:cb({"name":"hcoding"})  這是一段js代碼
?>

瀏覽器會發生什麼事呢,我就不說了,固然是cb方法被調用啦:

jsonp效果截圖

因此,再說jsonp的概念,利用<script>不受同源策略的限制,跨域的服務器把要返回的json數據做爲參數和回調函數一塊兒返回客戶端。

JQuery對JSONP的支持

本文要講ajax的跨域請求,前面說了那麼多,下面固然要講主題啦。

從 1.2 版本開始,jQuery 擁有對 JSONP 回調的本地支持。若是指定了 JSONP 回調,就能夠加載位於另外一個域的 JSON 數據,回調的語法爲:url?callback=?。jQuery 自動將 ? 替換爲要調用的生成函數名。

例子3

客戶端代碼:

<script>
    // 客戶端使用getJSON方法請求另外一臺機子上的腳本
    // 瀏覽器會生成一個隨機的callback參數
    $.getJSON("http://172.22.22.120/new/ajax_jsonp.php?callback=?",function(json){
        alert(json.website);
    });
</script>

服務端PHP腳本代碼:

<?php
    $cb = htmlspecialchars($_GET['callback']);  // 注意了,這裏要作好過濾,防止xss攻擊
    echo $cb,'(',json_encode(array('website'=>'hcoding')),')';  // 返回客戶端的數據,這是一段js代碼
?>

jsonp效果截圖

$.getJSON簡單易用,但就是不能指定回調函數。

例子4

客戶端代碼:

<script>
    $.ajax({
        type : "GET",
        url : "http://172.22.22.120/new/ajax_jsonp.php",
        dataType : "jsonp",    // 數據格式指定爲jsonp
        jsonp: "callback",     // 服務點經過這個鍵值獲取回調方法
        jsonpCallback:"cb",   // 指定回調方法
        success : function(json){

        },
    });  

    // 回調方法
    function cb(data){
        alert(data.website);
    }
</script>

服務端PHP腳本代碼和例子3的相同。

jsonp效果截圖

總結

正所謂無規矩不成方圓,以安全爲出發點,遵循同源策略是一個好品德。但咱們也有跨域請求的需求,jsonp就能知足咱們的需求。固然跨域請求還有不少的方法,不單止jsonp。

本文連接:http://www.hcoding.com/?p=238

原創文章,轉載請註明:JC&hcoding.com

相關文章
相關標籤/搜索