JSONP的起源

2008年09月13日 Web开发

作者:Bob Ippolito /原文链接

浏览器安全模型规定,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:


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

如果用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似乎没有什么,但我们可以要求服务器在数据有效时给出通知。因此,我可以编写一个用于跟踪数据的小系统:


var delicious_callbacks = {};
function getDelicious(callback, url) {
    var uid = (new Date()).getTime();
    delicious_callbacks[uid] = function () {
        delete delicious_callbacks[uid];
        callback();
    };
    url += "?jsonp=" + encodeURIComponent("delicious_callbacks[" + uid + "]");
    // add the script tag to the document, cross fingers
};

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


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

可见,由于使用圆括号括住了返回的数据,这就相当于把一个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日。



朋友们的留言

  1. hello cuckoo | 09月 16th, 2008 at 09:42

    中秋好。
    怎么把我的链接去掉了呢?
    给我做个链接可以吗???
    非常感谢!!
    我的EMAIL:[email protected]

    Reply to this comment
  2. vampire | 09月 16th, 2008 at 20:41

    大概是说通过script的src来实现跨域,通过经编码的json在url中传递数据?
    是不是说页面上的js生产带有不同参数的jsonp,通过src传递给服务端,服务端根据该jsonp返回相应数据?有点不太明白,能否提供一个实例?谢谢

    Reply to this comment
  3. admin | 09月 17th, 2008 at 20: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放到浏览器地址栏中,回车,即可看到结果。

    Reply to this comment
  4. hello cuckoo | 09月 17th, 2008 at 20:51

    管理员能回复下吗?
    不可以的话也说声。
    有劳了。
    :)

    Reply to this comment
  5. admin | 09月 17th, 2008 at 20:58

    给你回的邮件没收到吗?最近,网站空间提供商要求我们必须删除可能侵犯知识产权的链接。所以,就全都删除了。

    Reply to this comment
  6. vampire | 09月 19th, 2008 at 00:08

    @admin:嗯 明白了 实际上跟本地调用函数差不多 只不过通过src提交了请求并得到了具体数据参数 很聪明的办法 非常感谢

    去年就开始看你的博客了 只是来的很少 会继续关注你的博客:-)

    Reply to this comment
  7. hqlulu | 10月 13th, 2008 at 09:23

    function customCallback(obj){
    for(var i in obj)
    alert(i+”:”+obj[i]);
    }

    应该是类似这样

    Reply to this comment
  8. vampire | 10月 26th, 2008 at 16:53

    Javascript 使用 CSS 异步跨域获取数据:
    http://www.gracecode.com/Archive/Display/2469

    Reply to this comment
  9. 马士华 | 02月 19th, 2009 at 20:24

    在我的blog页面http://www.hadoop.org.cn/web/jsonp/上有实现思路和简单代码.
    JSONP的安全性值得思考.远程主机搞点恶意代码,用户可不知道你访问的是别人的主机.也只能怪罪于现在访问的站点了.

    Reply to this comment
  10. Websites tagged "jsonp" on Postsaver | 04月 14th, 2009 at 04:14

    [...] – JSONP的起源 saved by geeked2009-03-21 – 《尻 [...]

    Reply to this comment
  11. 使用jQuery及Bing API实现简易搜索引擎 - CSS9.NET | 06月 27th, 2009 at 22:54

    [...] 我们看到在使用jquery ajax时,指定数据类型为jsonp,jsonp是一种可跨域访问的协议,我对其也不是非常清楚,可以在这里了解一下。另外 CSS9.NET 也计划在后面的文章中讲解json的相关知识,敬请关注。 [...]

    Reply to this comment
  12. 关于“跨域”问题的总结 « Play Google | 04月 19th, 2010 at 13:55

    [...] jsonp(JSON with Padding): 简单点说,异步请求跨域的服务器端时,不是直接返回数据,而是返回一个js方法,把数据作为参数传过来。这需要服务器端稍作修改,如果只是跨域传递数据(而不是DOM操作),个人认为这种方式是最好的。参考内容:使用 JSONP 实现跨域通信 [...]

    Reply to this comment
  13. Juicy Couture | 12月 2nd, 2010 at 19:56

    感觉楼主很用心,会常来看你的文章和博客的。

    Reply to this comment
  14. juicy couture outlet | 02月 10th, 2011 at 15:49

    Excellently written article, if only all blogger offered the same level of content as you, the internet would be a much better place. Please keep it up!

    Reply to this comment
  15. 赵旭东 | 02月 24th, 2011 at 08:46

    jsonp大概知道有这么回事,一直用不到,看您这篇就清晰多了。

    Reply to this comment
  16. Marta Arnitz | 09月 15th, 2011 at 23:27

    Hello, Nice work! This is my first time i visit here. I discovered so numerous fascinating stuff in your website.

    Reply to this comment
  17. things to do lancaster | 09月 16th, 2011 at 00:18

    I am experiencing a situation with your rss feed . Don’t know why I am not able to subscribe to it. Is there anybody getting an identical rss problem? Anybody who is aware of kindly respond. Thanks

    Reply to this comment
  18. presentation techniques | 09月 16th, 2011 at 00:18

    Nice post. I study one thing on totally different blogs everyday. It’s going to always be stimulating to read content from different writers and observe a little bit something from their blog.

    Reply to this comment
  19. zildjian zbt | 09月 16th, 2011 at 00:21

    Thank you for all of the effort on this blog

    Reply to this comment
  20. gazeebo | 09月 16th, 2011 at 00:31

    Youre so cool! I dont suppose Ive read anything like this before. So nice to find somebody with some original thoughts on this subject.

    Reply to this comment
  21. cloud computing video tutorial | 09月 16th, 2011 at 01:07

    I was very pleased to find this website. I wanted to thank you for your time for this wonderful post!! I definitely enjoy reading it and I have you bookmarked to check out new stuff you blog post.

    Reply to this comment
  22. log home kits | 09月 16th, 2011 at 01:12

    This really answered my problem, thank you!

    Reply to this comment
  23. lyophilization | 09月 16th, 2011 at 01:13

    Your place is valueble for me. Thanks!…

    Reply to this comment
  24. computer repair columbus ohio | 09月 16th, 2011 at 01:14

    This is the best web blog I have read.

    Reply to this comment
  25. travel advisor | 09月 16th, 2011 at 01:24

    Good day I am so grateful I found your site, I really found you by mistake, while I was researching on Aol for something else, Anyhow I am here now and would just like to say many thanks for a remarkable post and a all round thrilling blog (I also love the theme/design), I don’t have time to read it all at the minute but I have saved it and also included your RSS feeds, so when I have time I will be back to read a lot more, Please do keep up the excellent job.

    Reply to this comment
  26. volkswagen philadelphia | 09月 16th, 2011 at 01:30

    This was a great post, thanks for the info.

    Reply to this comment
  27. kitchen remodeling lancaster | 09月 16th, 2011 at 01:36

    Hardly ever do I encounter a weblog that’s both educated and entertaining, and let me let you know, you have hit the nail on the head. Your thought is excellent; the issue is something that not sufficient individuals are speaking intelligently about. I am very happy that I stumbled across this in my quest for info relating to this.

    Reply to this comment
  28. indianapolis mortgage | 09月 16th, 2011 at 02:05

    I definitely enjoy every little bit of it and I have bookmarked your blog.

    Reply to this comment
  29. computers fargo | 09月 16th, 2011 at 02:12

    Thanks for spending the time to discuss this, I feel strongly about it and love reading more on this topic.

    Reply to this comment
  30. plumbing lancaster | 09月 16th, 2011 at 02:17

    It’s hard to find knowledgeable people on this topic, but you sound like you know what you’re talking about! Thanks

    Reply to this comment
  31. cloud computing providers | 09月 16th, 2011 at 02:18

    I really relate to that post. Thanks for the info.

    Reply to this comment
  32. new mover | 09月 16th, 2011 at 02:21

    Wow, I enjoyed your neat post.

    Reply to this comment
  33. restaurants lancaster | 09月 16th, 2011 at 02:33

    Aw, this was a very nice post. In thought I want to write like this – taking time and actual effort to make a very good article is very rare…

    Reply to this comment
  34. ford edge | 09月 16th, 2011 at 02:36

    Thanks for spending the time to discuss this, I feel strongly about it and love studying more on this topic. If attainable, as you develop into an expert, would you mind updating your weblog with more details?

    Reply to this comment
  35. sectional garage | 09月 16th, 2011 at 02:41

    It’s hard to find knowledgeable people on this topic, but you sound like you know what you’re talking about! Thanks

    Reply to this comment
  36. NFL Jerseys | 11月 4th, 2011 at 08:54

    His times using the Bears started to be numbered using the signing of Marion Barber, and any attempts to business him went nowhere. but do not exercise using the team. He is anticipated to participate in Wednesday’s workout and be available when Arizona opens its time period Sunday at house against the Carolina Panthers.<yangchengbin/201111

    Reply to this comment
  37. cheap handbags | 11月 6th, 2011 at 20:55

    Thanks for your opinion. discount handbags I totally like with it.I like cheap designer handbags as well and someone is looking for cheap handbags People usually prefer fake designer handbags, especially when they visit some handbags outlet. In some areas,people like to wholesale clothing. They will find some store doing very cheap or discounted Chanel Handbags outlet. Certainly, is a good way to earn money. designer handbags outlet

    Reply to this comment
  38. china wholesale | 11月 7th, 2011 at 15:59

    Hi, the article is so wonderful, I am interested in it. I will pay attention to your articles.

    Reply to this comment
  39. Ugg Boots | 11月 7th, 2011 at 15:59

    Thank you for your articles

    Reply to this comment
  40. cheap jerseys | 11月 12th, 2011 at 10:53

    They will find some store doing very cheap or discounted Chanel Handbags outlet.

    Reply to this comment
  41. christian louboutins on sale | 11月 18th, 2011 at 11:13

    Full exercise of the thigh muscles, exercise, and to exercise Christian Louboutin Pumps for sale their legs, and then full massage to be able to gradually improve the sturdy legs of trouble.

    Reply to this comment
  42. 2011 Pro Bowl | 11月 21st, 2011 at 15:37

    NFL spokesman Greg Aiello acknowledged the discussions using the Colts greater compared to weekend. “The team completely understood the problems and committed to addressing them,” Aiello mentioned in an electric mail toward the connected Press.”We have been informed last evening of the choice reached by the team and Mr. Tressel. We think it is appropriate.”
    In a statement, Polian mentioned that “questions have been raised with respect toward the equity of his appointment as opposed to suspensions getting serves this season by present and previous Ohio State players.” yangchengbin/201111

    Reply to this comment
  43. moncler0utlet | 12月 6th, 2011 at 16:06

    is a good article for us ,i have been find everywhere for this kind of point ,All Moncler products are produced by Original Brand from Manufacturer.yangchengbin/201112

    Reply to this comment
  44. bridal wedding dresses | 12月 12th, 2011 at 14:50

    good arctile , thanks for sharing it and please keep doing this good job .

    Reply to this comment
  45. one shoulder wedding dresses | 01月 4th, 2012 at 13:18

    good post , i like it , thanks for sharing it . have a nice day .

    Reply to this comment

我来说两句儿

可以在留言中使用以下标签 :<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Spam Protection by WP-SpamFree