JSONP和JSON之间有什么联系吗?

JSON(JavaScript Object Notation) 是一种轻量级、可读的基于文本的的数据交换格式。,是一种轻量的数据交换开放标准。源于JavsScript编程语言中对简单数据结构和关联数组的展示功能。它是仅含有数据对和简单括号结构的纯文本,因此可通过许多途径进行JSON消息的传递。对于JSON大家应该是很了解了吧,不是很清楚的朋友可以去json.org上了解下。

1. JSONP定义
    JSONP是英文JSON with Padding的缩写,是一个非官方的协议。它允许在服务器端生成script tags返回至客户端,通过javascript callback的形式来实现跨域访问(这仅仅是JSONP简单的实现形式)--来源百度。 JSONP是一种script tag的注入,将server返回的response添加到页面实现特定功能。

2.JSONP由来

要解释JSONP的来由,先要说一下浏览器的“同源策略(SOP:Same Origin Policy)”。 简而言之,就是浏览器限制脚本程序只能和同协议、同域名、同端口的脚本进行交互,这包括共享和传递变量等。cookie的传递也是遵从同样策略。这就造成 一些涉及到多个服务器的应用在整合时一些麻烦。跨域访问的问题造成A站点的Ajax代码无法访问B站点的数据。

如何解决跨域访问呢?那就要借助浏览器 的一个特性:尽管浏览器不允许页面中的脚本程序跨域读取数据,但却允许HTML引用跨域的资源,如图片,CSS和脚本程序。对于脚本程序的引用比较特殊, 它被浏览器解析以后,就和本地的脚本程序别无二致且可立即进行解释并执行。如在B站点的一个js文件,一个简单的提示框:alert(“This is Victor!”);。在A站点引用这个js,这个脚本就会在B站点的应用中执行,显示一个alert信息。由于站外脚本的引用是通过script tag来实现的,而脚本程序又可通过DOM的方式可以对HTML页面的所有标签进行控制(包括动态的创建script标签),这就可以实现通过调用站外程 序对本地资源进行更改了。另外,通过<script> 标记的使用,就可从服务端直接返回可执行的JavaScript函数调用或者JSON数据。

 3. JSONP原理--CallBack
    首先在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成 JSON数据。然后以JavaScript 语法的方式,生成一个function, function名字就是传递上来的参数jsonp.

然后,将JSON数据直接以入参的方式,放置到function中,这样就生成了一段 js 语法的文档,返回给客户端。
    最后,在客户端浏览器中解析script标签,并执行返回的JavaScript文档,此时数据作为参数,传入到了客户端预先定义好的回调函数里(动态执行回调函数) 。

其实 JSONP是个很简单的一个东西。主要是利用了 <script/>标签对javascript文档的动态解析来实现。(其实也可以用eval函数)

JSONP实现代码:

//远程服务器js文件代码:
localHandler({"result":"我是远程js带来的数据"});//本地服务器下html页面代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title></title><script type="text/javascript">var localHandler = function(data){alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);};</script><script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>
</body>
</html>

运行之后查看结果,页面成功弹出提示窗口,显示本地函数被跨域的远程js调用成功,并且还接收到了远程js带来的数据。很欣喜,跨域远程获取数据的目的基 本实现了,但是又一个问题出现了,我怎么让远程js知道它应该调用的本地函数叫什么名字呢?毕竟是jsonp的服务者都要面对很多服务对象,而这些服务对 象各自的本地函数都不相同啊?

这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数(localHandler),然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调

将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义吧。

上面的例子是最简单的JSONP的实现模型,不过它还算不上一个真正的JSONP服务。我们来看一下真正的JSONP服务是怎么样的,比如Google的ajax搜索接口:http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=?&callback=?

  • q=?这个问号是表示你要搜索的内容,最重要的是第二个callback=?这个是正如其名表示回调函数的名称,也就是将你自己在客户端定义的 回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调。

本地服务器下html页面代码改为:

<!DOCTYPE html>
<html>
<head><title></title><script type="text/javascript">// 得到航班信息查询结果后的回调函数var flightHandler = function(data){alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');};// 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";// 创建script标签,设置其属性var script = document.createElement('script');script.setAttribute('src', url);// 把script标签加入head,此时调用开始document.getElementsByTagName('head')[0].appendChild(script);</script>
</head>
<body>
</body>
</html>

服务器端的js

flightHandler({"code": "CA1998","price": 1780,"tickets": 5
});

4. jQuery对JSONP的实现

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head><title>Untitled Page</title><script type="text/javascript" src=jquery.min.js"></script><script type="text/javascript">jQuery(document).ready(function(){$.ajax({type: "get",async: false,url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",dataType: "jsonp",jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据success: function(json){alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');},error: function(){alert('fail');}});});</script></head><body></body></html>

是不是有点奇怪?为什么这次没有写flightHandler这个函数呢?而且竟然也运行成功了!哈哈,这就是jQuery的功劳了,jquery在处 理jsonp类型的ajax时,自动帮你生成回调函数并 把数据取出来供success属性方法来调用

5.用 Java servlet 实现的 JSONP 服务

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String jsonData = getDataAsJson(req.getParameter("symbol"));String output = req.getParameter("callback") + "(" + jsonData + ");";resp.setContentType("text/javascript");          PrintWriter out = resp.getWriter();out.println(output);// prints: jsonp1232617941775({"symbol" : "IBM", "price" : "91.42"});
}

6. 现成的 JSONP 服务

知道如何使用 JSONP 之后,可以开始使用一些现成的 JSONP Web 服务来构建应用程序和 mashup。下面为接下来的开发项目做准备。

  • Digg API:来自 Digg 的头条新闻:http://services.digg.com/stories/top?appkey=http%3A%2F%2Fmashup.com&type=javascript&callback=?
  • Geonames API:邮编的位置信息:http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=?
  • Flickr API:来自 Flickr 的最新猫图片: http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=?
  • Yahoo Local Search API:在邮编为 10504 的地区搜索比萨:http://local.yahooapis.com/LocalSearchService/V3/localSearch?appid=YahooDemo&query=pizza&zip=10504&results=2&output=json&callback=?

说明:

  • ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;
  • 但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。
  • 所以说,其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。
  • 还有就是,jsonp是一种方式或者说非强制性协议,如同ajax一样,它也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。

JSONP的缺陷

JSONP 是构建 mashup 的强大技术,但不幸的是,它并不是所有跨域通信需求的万灵药。它有一些缺陷,必须认真考虑它们。

  • 第一,也是最重要的一点,没有关于 JSONP 调用的错误处理。如果动态脚本插入有效,就执行调用;如果无效,就静默失败。失败是没有任何提示的。例如,不能从服务器捕捉到 404 错误,也不能取消或重新开始请求。不过,等待一段时间还没有响应的话,就不用理它了。(未来的 jQuery 版本可能有终止 JSONP 请求的特性)。
  • 第二, JSONP 被不信任的服务使用时会很危险。因为 JSONP 服务返回打包在函数调用中的 JSON 响应,而函数调用是由浏览器执行的,这使宿主 Web 应用程序更容易受到各类攻击。如果打算使用 JSONP 服务,了解它能造成的威胁非常重要。

参考:

  • 说说JSON和JSONP,也许你会豁然开朗
  • JSONP简介
  • 深入浅出JSONP--解决ajax跨域问题
  • 使用 JSONP 实现跨域通信,第 1 部分: 结合 JSONP 和 jQuery 快速构建强大的 mashup

转载于:https://www.cnblogs.com/JoannaQ/p/3511577.html

JSONP的学习(收集整理)相关推荐

  1. 架构师速成6.6-知识的收集整理学习

    知识如何学习前面已经讲了2节,这节主要讲知识的整理和沉淀. 其实我之前也一直没有好好的思考过这个问题,今天在整理自己的wiz知识库的时候突发灵感,所以有了这一节. 其实知识获取的过程分为搜索-> ...

  2. 声明:此资源由本博客收集整理于网络,只用于交流学习,请勿用作它途。如有侵权,请联系, 删除处理。...

    声明:此资源由本博客收集整理于网络,只用于交流学习,请勿用作它途.如有侵权,请联系, 删除处理. 转载于:https://www.cnblogs.com/hackhyl/p/11365581.html

  3. python数据收集整理教案_数据收集整理教案讲解学习

    一.数据收集整理 第一课时 教学目标 初步体验数据收集. 整理. 描述的过程, 会用分类数数的方法将数据整理成 简单的统计表, 初步认识统计表, 能正确填写统计表, 能从中获得简单统计的结 果. 通过 ...

  4. vc++学习精髓(收集,整理)

    vc++学习精髓(收集,整理) 以下是很多VC爱好者的学习经历,希望对大家有所帮助: 我记得我在网上是这么说的:先学win32的SDK,也就是API, 再学MFC,这么一来呢,就先有个基础,MFC是A ...

  5. 前端学习资料网址收集整理

    前端学习资料整理:百度cdn,jquery插件网站收集,html5资料整理等.方便查阅. A:基础知识,行业动态 http://www.51cto.com 51cto http://www.html5 ...

  6. linux操作系统学习网站整理(100个)

    linux操作系统学习网站整理(100个) 评选出的这100个优秀站点,将按照下述20个类别作以评介: (一) 文件下载 (二) 幽默娱乐 (三) 相关新闻 (四) 通用硬体 (五) 专用硬体 (六) ...

  7. Deep Learning(深度学习)学习笔记整理系列之(二)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  8. SIMD学习笔记整理(索引贴)

    说明]:本系列笔记主要转载自网上的资源,版权归网上的各路牛人,本人只是在牛人的基础上结合自己的实践对一些笔记进行整理,添加自己的心得和一些代码.感谢网上未曾谋面的大牛们! [转载]:SIMD函数整理: ...

  9. python数据收集整理教案_《数据收集整理(例1)》教案

    <数据收集整理(例 1 )>名师教案 中原区伊河路小学 褚瑞婕 一.学习目标 (一)学习内容 <义务教育教科书数学> (人教版) 二年级下册第 2 页例 1 相关内容及做一做. ...

  10. Web环境下使用Starling出现的问题收集整理

    FlashBuilder环境下使用Starling出现的问题收集整理 刚开始学习Starling框架,遇到了不少问题,苦于无解,向Starling中文交流群求助.问题得到一 一解决.在这里非常感谢他们 ...

最新文章

  1. Generator的正确打开方式
  2. django 文档生成器
  3. vmware添加新硬盘 挂载新硬盘 硬盘扩容
  4. 【web必知必会】—— 图解HTTP(下)
  5. 如何在Excel中使用VB宏连接SAP系统
  6. ubuntu 新增mysql用户_Ubuntu中给mysql添加新用户并分配权限
  7. P6688-可重集【字符串hash,线段树】
  8. LeetCode题解 343.Integer Break
  9. DMA及cache一致性的学习心得 --dma_alloc_writecombine
  10. 【Flink】ExceptionInChainedOperatorException: Could not forward element to next operator Buffer
  11. JZYZOJ1140 飞船控制站
  12. 电脑获取服务器IP,ping nslookup获取心知天气的IP地址,windows cmd命令行进行DNS域名解析解析
  13. 2010年中考英语写作高分指导
  14. 电流(或电压)的平均值与有效值
  15. Manjaro 清理垃圾
  16. 客户的sample和项目计划
  17. 《人生哲理》二.人生苦短,别懂得太晚了...
  18. 微信广告转化统计java,百度推广oCPC微信号复制转化次数统计系统数据接口
  19. Workbook 对象 应用示例
  20. 多叉路口交通灯问题,输入任意道口数输出排序解决方案

热门文章

  1. 新入公司 问问题 ,快速了解代码的方法
  2. 数字签名、数字证书、对称加密算法、非对称加密算法、单向加密(散列算法)
  3. 使用SSH上传部署WAR包到服务器
  4. Swift 单元测试
  5. 架构师应具备的概要技能
  6. C#定时清理内存,net网页端可以尝试使用
  7. 如何修改PHP的memory_limit限制
  8. 微信小程序客服消息使用指南
  9. CentOS 6.5 手动rpm包安装gcc、g++
  10. Python-基础知识-常用模块