<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    憨厚生

    ----Java's Slave----
    ***Java's Host***

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      165 隨筆 :: 17 文章 :: 90 評論 :: 0 Trackbacks
    轉 http://www.cn-cuckoo.com/2008/09/13/the-origin-of-jsonp-262.html

    瀏覽器安全模型規定,XMLHttpRequest、框架(frame)等只能在一個域中通信。從安全角度考慮,這個規定很合理;但是,也確實給分布式(面向服務、混搭等等本周提到的概念)Web開發帶來了麻煩。

    為了實現跨域通信,通常的解決方案有3種:

    本地代理:
    需要一些硬件設施(沒有服務器的客戶端無法運行),并且帶寬和潛伏時間也要加倍(遠程服務器-代理服務器-客戶端)。

    Flash:
    遠程主機中需要部署一個crossdomain.xml文件,而且,Flash作為一門專有技術,其前途尚不明朗;換句話說,開發人員很可能要學習一種目標不確定的編程語言。

    Script標簽:
    無法確切知道內容是否有效,沒有標準的實現方法,又可能被認為是一種“安全風險”。


    在此,我建議使用一種新技術,也是一種獨立于標準的方法,即通過script標簽來跨域獲取數據,名為JSON with Padding,或者就叫JSONP。JSONP的原理很簡單,但需要服務器端給予相應配合。大致來說,JSONP的實現思路就是在客戶端編程時作好使用JSON數據的準備,然后再通過圓括號將這些數據括起來以創建一條有效的JavaScript語句(可能是一次有效的函數調用)。

    也就是說,客戶端可以使用一個用于命名jsonp的查詢參數來決定可以獲取的數據。最簡單的情況下,如果jsonp參數為空,則返回的數據就是被括在圓括號中的JSON。

    下面,我們就以del.icio.us的JSON API為例,來說明JSONP的原理。該API有一個“script tag”變量(即,可以將下面的URL作為script標簽的src屬性值,用以加載del.icio.us這個API提供的數據。——譯者注)如下所示:

    http://del.icio.us/feeds/json/bob/mochikit+interpreter:

    1. if(typeof(Delicious) == 'undefined') Delicious = {};
    2. Delicious.posts = [{
    3. "u": "http://mochikit.com/examples/interpreter/index.html",
    4. "d": "Interpreter - JavaScript Interactive Interpreter",
    5. "t": [
    6. "mochikit","webdev","tool","tools",
    7. "javascript","interactive","interpreter","repl"
    8. ]
    9. }]

    如果用JSONP的方式來表示,那么與此具有相同語義的URL應該是這樣的:

    http://del.icio.us/feeds/json/bob/mochikit+interpreter?
    jsonp=if(typeof(Delicious)%3D%3D%27undefined%27)
    Delicious%3D%7B%7D%3BDelicious.posts%3D

    單純看這個URL似乎沒有什么,但我們可以要求服務器在數據有效時給出通知。因此,我可以編寫一個用于跟蹤數據的小系統:

    1. var delicious_callbacks = {};
    2. function getDelicious(callback, url) {
    3. var uid = (new Date()).getTime();
    4. delicious_callbacks[uid] = function () {
    5. delete delicious_callbacks[uid];
    6. callback();
    7. };
    8. url += "?jsonp=" + encodeURIComponent("delicious_callbacks[" + uid + "]");
    9. // 手工輸入代碼,向文檔中插入script標簽
    10. };
    11.  
    12. getDelicious(doSomething, "http://del.icio.us/feeds/json/bob/mochikit+interpreter");

    根據以上假設,用于獲取數據的URL應該如下所示:
    http://del.icio.us/feeds/json/bob/mochikit+interpreter?jsonp=delicious_callbacks%5B12345%5D

    1. delicious_callbacks[12345]([{
    2. "u": "http://mochikit.com/examples/interpreter/index.html",
    3. "d": "Interpreter - JavaScript Interactive Interpreter",
    4. "t": [
    5. "mochikit","webdev","tool","tools",
    6. "javascript","interactive","interpreter","repl"
    7. ]
    8. }])

    可見,由于使用圓括號括住了返回的數據,這就相當于把一個JSONP請求轉化成了一次函數調用,或者得到了一個純粹的JSON直接量。服務器所要配合做的,就是在JSON數據的開頭添加一小段文本(即回調函數的名稱。——譯者注)并將JSON數據放在括號中!

    當然,接下來最好是使用Mochikit、Dojo等框架來抽象JSONP,從而讓自己省去動手編寫DOM以插入script標簽的麻煩。

    沒錯,JSONP只是解決了標準化的問題。假如遠程主機想通過script標簽向頁面中注入惡意代碼,而不是返回JSON數據,那么頁面安全可能會 隨時受到威脅。不過,一旦實現了JSONP,那么對開發人員來說肯定是一件省時省力的大好事,在此基礎上各種一般化的抽象、教程及文檔也會應運而生的。

    注:縮寫詞 JSONP 由 Bob Ippolito 在一篇名為 “Remote JSON - JSONP” 的文章中提出。但許多支持以 JSONP 技術實現跨域通信的廠商沒有稱其為 JSONP。例如,雅虎公司就稱這種技術為 “JSON with callbacks”。另外,原文發表于2005年12月5日。

    留言(9)

    hello cuckoo九月 16th, 2008 at 9:42 上午

    中秋好。
    怎么把我的鏈接去掉了呢?
    給我做個鏈接可以嗎???
    非常感謝!!
    我的EMAIL:hardcometure@163.com

    vampire九月 16th, 2008 at 8:41 下午

    大概是說通過script的src來實現跨域,通過經編碼的json在url中傳遞數據?
    是不是說頁面上的js生產帶有不同參數的jsonp,通過src傳遞給服務端,服務端根據該jsonp返回相應數據?有點不太明白,能否提供一個實例?謝謝

    admin九月 17th, 2008 at 8:43 下午

    @vampire

    你的理解是對的,看來我的翻譯你能看明白,呵呵。使用JSONP技術時,一般是由JS在客戶端頁面中動態插入script標簽,將其src屬性設置 為帶參數的URL。當頁面加載時,前述URL會將參數通過GET請求發送到相應服務器端應用程序(由URL表示),服務器根據參數返回數據——注意,這個 數據格式是JSON,并且(注意)被包含在一個函數調用中,例如:callback({json_data})。這樣,在客戶端頁面中存在預定義的 callback(data)函數的定義時,服務器返回的函數調用就會立即執行,由客戶端的函數對數據進行操作。

    實際的例子有很多,如Yahoo Search、Google Base、Flickr Search、Amazon Search等等。要學習和使用這些站點提供的支持JSONP的API,一般要注意兩點:一是有的站點要求注冊密鑰(使用時必須放到參數中),二是要注意 參數的使用方法。例如,有的API要求使用預定義的回調函數,而有的API則允許使用者自己定義回調函數。

    下面就是向Flickr Search請求JSONP響應的URL,其中使用了預定義的回調函數jsonFlickrApi(參數中不必給出):

    http://api.flickr.com/services/rest/
    ?method=flickr.photos.search
    &api_key=85618ad7d326d8ef93c6bee9ed32706f
    &per_page=5&format=json&text=china

    下面這個URL發送到Google Base,它允許開發人員使用自己定義的回調函數:

    http://www.google.com/base/feeds/snippets
    ?q=jquery
    &alt=json-in-script
    &callback=customCallback

    把前面的URL放到瀏覽器地址欄中,回車,即可看到結果。



    posted on 2009-03-24 21:34 二胡 閱讀(538) 評論(0)  編輯  收藏 所屬分類: JSweb系統開發
    主站蜘蛛池模板: 国产精品亚洲精品日韩动图| 亚洲国产成人超福利久久精品| 毛片网站免费在线观看| 精品免费国产一区二区| 国产91精品一区二区麻豆亚洲| 激情婷婷成人亚洲综合| 国产猛烈高潮尖叫视频免费| mm1313亚洲国产精品无码试看| 日本xxwwxxww在线视频免费| 亚洲动漫精品无码av天堂| 永久免费A∨片在线观看| 99ri精品国产亚洲| 一区二区三区免费视频网站| 免费少妇a级毛片人成网| 一级特黄a大片免费| 国产亚洲3p无码一区二区| 99在线观看精品免费99| 国内精品久久久久久久亚洲| 成年女人A毛片免费视频| 亚洲AV日韩AV永久无码下载| 亚洲视频免费观看| 亚洲va久久久噜噜噜久久天堂| 免费人成黄页在线观看日本| 五月婷婷亚洲综合| a毛片免费在线观看| 亚洲国产精品一区二区第一页免 | 成年人视频免费在线观看| 激情亚洲一区国产精品| 国产无遮挡吃胸膜奶免费看视频| 一级毛片大全免费播放下载| 久久精品国产精品亚洲艾 | 国产精品视频白浆免费视频| 亚洲第一视频在线观看免费| a级成人毛片免费视频高清| 亚洲综合视频在线| 永久久久免费浮力影院| 中文字幕无码毛片免费看| 91亚洲性爱在线视频| 国产免费观看a大片的网站| 亚洲欧美日韩一区二区三区| 国产亚洲自拍一区|