JSONP (JSON with Padding)

JSONP 的全名是 JSON with Padding,JSONP 是 JSON 的一種使用模式,可以讓一個網頁從其他的網域 (cross-domain) 請求資料,繞過 AJAX 因為有瀏覽器安全性限制無法跨網域使用的問題 (same-origin policy)。

JSONP 和 JSON 其實也沒有什麼直接的關係,只是搭配 JSON 是純文字格式方便傳輸且支援豐富的資料交換格式,另外 JavaScript 原生就可以直接操作 JSON,讓 JSONP 這個使用模式更方便好用。

JSONP 是解決跨網域限制的方法之一,它的概念其實很簡單,就是利用 <script> 標籤可以跨網域請求的特性。

整個 JSONP 過程的步驟大概像是:

  1. 用 JavaScript 動態建立一個 <script> 標籤元素,並指定好 src 指向一個跨網域的網址,例如 https://api.flickr.com/services/feeds/photos_public.gne?tags=kitten&format=json&jsoncallback=myCallback

  2. 遠端伺服器接收到請求後會返回一個 JavaScript 檔案 (application/javascript),該 JavaScript 檔案中會直接執行一個 JavaScript function,而這個 function 的傳入參數就是你想要請求的資料結果,參數的格式通常就是一個 JSON,其實也就是 JavaScript 的 object literal 所以是直接可以讀取的!

    此外,執行的 function 名稱通常是可以透過請求的 URL 參數指定的,像是上面例子中的 URL "jsoncallback=myCallback" 參數就是用來指定將 JSON 傳入 myCallback 這個函數並執行。

  3. 最後在 callback function 中你就可以對 server 返回的資料做任何事啦。

以上就是 JSONP 的運作概念,是不是還蠻簡單的!

請求 https://api.flickr.com/services/feeds/photos_public.gne?tags=kitten&format=json&jsoncallback=myCallback 返回的結果內容大概會像是這樣子:

myCallback({
    "title": "Recent Uploads tagged kitten",
    "link": "https:\/\/www.flickr.com\/photos\/tags\/kitten\/",
    "description": "",
    "modified": "2016-12-25T09:15:04Z",
    "generator": "https:\/\/www.flickr.com",
    "items": [{
        "title": "Hello Big World",
        "link": "https:\/\/www.flickr.com\/photos\/4kleuren\/6087794345\/",
        "media": {
            "m": "https:\/\/farm7.staticflickr.com\/6202\/6087794345_eacfba9149_m.jpg"
        },
        "date_taken": "2016-01-01T00:00:00-08:00",
        "description": " <p><a href=\"https:\/\/www.flickr.com\/people\/4kleuren\/\">gill4kleuren - 13 ml views<\/a> posted a photo:<\/p> <p><a href=\"https:\/\/www.flickr.com\/photos\/4kleuren\/6087794345\/\" title=\"Hello Big World\"><img src=\"https:\/\/farm7.staticflickr.com\/6202\/6087794345_eacfba9149_m.jpg\" width=\"240\" height=\"149\" alt=\"Hello Big World\" \/><\/a><\/p> ",
        "published": "2016-12-25T09:15:04Z",
        "author": "nobody@flickr.com (\"gill4kleuren - 13 ml views\")",
        "author_id": "98216376@N00",
        "tags": "cat kitty kitten poes eyes beauty lovely red kat pet animal collage pussycat pussy poezen outdoor world shunset hair little mammal indoor people"
    },
    {
        "title": "Wolfit 0008",
        "link": "https:\/\/www.flickr.com\/photos\/stagedoor\/31486928600\/",
        "media": {
            "m": "https:\/\/farm1.staticflickr.com\/441\/31486928600_6e09e1e1f6_m.jpg"
        },
        "date_taken": "2016-12-24T12:48:04-08:00",
        "description": " <p><a href=\"https:\/\/www.flickr.com\/people\/stagedoor\/\">stagedoor<\/a> posted a photo:<\/p> <p><a href=\"https:\/\/www.flickr.com\/photos\/stagedoor\/31486928600\/\" title=\"Wolfit 0008\"><img src=\"https:\/\/farm1.staticflickr.com\/441\/31486928600_6e09e1e1f6_m.jpg\" width=\"240\" height=\"180\" alt=\"Wolfit 0008\" \/><\/a><\/p> <p>Wolfit, Xmas Eve, aged 12 weeks. Just finished the preliminary setting up of the new camera. Hand held, not good light, lively subject!<br \/> <br \/> Wolfit Pussycat, Scarborough<br \/> Xmas Eve 2016<\/p>",
        "published": "2016-12-25T08:44:06Z",
        "author": "nobody@flickr.com (\"stagedoor\")",
        "author_id": "12494104@N00",
        "tags": "wolfit cat moggie tabby pussy kitten scarborough yorkshire england olympus uk omd em1mkii copyright"
    }]
})

一般 JSONP 不會設計用來傳輸隱私性高的資料,因為比較容易遭受到像是 CSRF 攻擊的安全性問題。