一.前言
现在富Web开发,太多交互是通过AJAX来实现的。
当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socket通讯和本地数据库功能,又或者通过HTML5的WebSocket也可以实现与服务器的通讯和服务端推功能,但这两种方式都有其局限性,前者需要PhoneGap支持,后者要求用户设备必须支持WebSocket,因此都不能算是ST2的原生解决方案,原生的只有AJAX。
说到AJAX就会不可避免的面临两个问题,第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?这两个问题目前都有不同的解决方案,比如数据可以用自定义字符串或者用XML来描述,跨域可以通过服务器端代理来解决。
但到目前为止最被推崇或者说首选的方案还是用JSON来传数据,靠JSONP来跨域。
JSON和JSONP虽然只有一个字母的差别,但其实他们根本不是一回事儿:JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。我们拿最近比较火的谍战片来打个比方,JSON是地下党们用来书写和交换情报的“暗号”,而JSONP则是把用暗号书写的情报传递给自己同志时使用的接头方式。看到没?一个是描述信息的格式,一个是信息传递双方约定的方法。
二.什么是JSON?
前面简单说了一下,JSON是一种基于文本的数据交换方式,或者叫做数据描述格式,你是否该选用他首先肯定要关注它所拥有的优点。
1.JSON的优点:
a.基于纯文本,跨平台传递极其简单;
b.Javascript原生支持,后台语言几乎全部支持;
c.轻量级数据格式,占用字符数量极少,特别适合互联网传递;
d.可读性较强,虽然比不上XML那么一目了然,但在合理的依次缩进之后还是很容易识别的;
e.容易编写和解析,当然前提是你要知道数据结构;
JSON的缺点当然也有,但在作者看来实在是无关紧要的东西,所以不再单独说明。
2.JSON的格式或者叫规则:
JSON能够以非常简单的方式来描述数据结构,XML能做的它都能做,因此在跨平台方面两者完全不分伯仲。
a.JSON只有两种数据类型描述符,大括号{}和方括号[],其余英文冒号:是映射符,英文逗号,是分隔符,英文双引号""是定义符。
b.大括号{}用来描述一组“不同类型的无序键值对集合”(每个键值对可以理解为OOP的属性描述),方括号[]用来描述一组“相同类型的有序数据集合”(可对应OOP的数组)。
c.上述两种集合中若有多个子项,则通过英文逗号,进行分隔。
d.键值对以英文冒号:进行分隔,并且建议键名都加上英文双引号"",以便于不同语言的解析。
e.JSON内部常用数据类型无非就是字符串、数字、布尔、日期、null 这么几个,字符串必须用双引号引起来,其余的都不用,日期类型比较特殊,这里就不展开讲述了,只是建议如果客户端没有按日期排序功能需求的话,那么把日期时间直接作为字符串传递就好,可以省去很多麻烦。
3.JSON实例:
// 描述一个人 var person = { "Name": "Bob", "Age": 32, "Company": "IBM", "Engineer": true } // 获取这个人的信息 var personAge = person.Age; // 描述几个人 var members = [ { "Name": "Bob", "Age": 32, "Company": "IBM", "Engineer": true }, { "Name": "John", "Age": 20, "Company": "Oracle", "Engineer": false }, { "Name": "Henry", "Age": 45, "Company": "Microsoft", "Engineer": false } ] // 读取其中John的公司名称 var johnsCompany = members[1].Company; // 描述一次会议 var conference = { "Conference": "Future Marketing", "Date": "2012-6-1", "Address": "Beijing", "Members": [ { "Name": "Bob", "Age": 32, "Company": "IBM", "Engineer": true }, { "Name": "John", "Age": 20, "Company": "Oracle", "Engineer": false }, { "Name": "Henry", "Age": 45, "Company": "Microsoft", "Engineer": false } ] } // 读取参会者Henry是否工程师 var henryIsAnEngineer = conference.Members[2].Engineer;关于JSON,就说这么多,更多细节请在开发过程中查阅资料深入学习。
三.什么是JSONP?
1.先说说JSONP是怎么产生的:
其实网上关于JSONP的讲解有很多,但却千篇一律,而且云里雾里,对于很多刚接触的人来讲理解起来有些困难,小可不才,试着用自己的方式来阐释一下这个问题,看看是否有帮助。
a.一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准;
b.不过我们又发现,Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有"src"这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>);
c.于是可以判断,当前阶段如果想通过纯web端(ActiveX控件、服务端代理、属于未来的HTML5之Websocket等方式不算)跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理;
d.恰巧我们已经知道有一种叫做JSON的纯字符数据格式可以简洁的描述复杂数据,更妙的是JSON还被js原生支持,所以在客户端几乎可以随心所欲的处理这种格式的数据;
e.这样子解决方案就呼之欲出了,web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。
f.客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常像AJAX,但其实并不一样。
g.为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
如果对于callback参数如何使用还有些模糊的话,后面会有具体的实例来讲解。
2.JSONP的客户端具体实现:
不管jQuery也好,extjs也罢,又或者是其他支持jsonp的框架,他们幕后所做的工作都是一样的,下面我来循序渐进的说明一下jsonp在客户端的实现:
a.我们知道,哪怕跨域js文件中的代码(当然指符合web脚本安全策略的),web页面也是可以无条件执行的。
远程服务器根目录下有个remote.js文件代码如下:
alert('我是远程文件');
本地服务器下有个jsonp.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" src="http://127.0.0.1:8080/RemoteService/remote.js"></script> </head> <body> </body> </html>
毫无疑问,页面将会弹出一个提示窗体,显示跨域调用成功。如下所示:
b.现在我们在jsonp.html页面定义一个函数,然后在远程remote.js中传入数据进行调用。
jsonp2.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://127.0.0.1:8080/RemoteService/remote2.js"></script> </head> <body> </body> </html>remote2.js文件代码如下:
localHandler({"result":"我是远程js带来的数据"});

显示本地函数被跨域的远程js调用成功,并且还接收到了远程js带来的数据。很欣喜,跨域远程获取数据的目的基本实现了,但是又一个问题出现了,我怎么让远程js知道它应该调用的本地函数叫什么名字呢?毕竟是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></title> <script type="text/javascript"> // 得到航班信息查询结果后的回调函数 var flightHandler = function(data){ alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。'); }; // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码) var url = "http://127.0.0.1:8080/RemoteService/flightResult.html?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文件写死,而是编码实现动态查询,而这也正是jsonp客户端实现的核心部分,本例中的重点也就在于如何完成jsonp调用的全过程。
我们看到调用的url中传递了一个code参数,告诉服务器我要查的是CA1998次航班的信息,而callback参数则告诉服务器,我的本地回调函数叫做flightHandler,所以请把查询结果传入这个函数中进行调用。
OK,服务器很聪明,这个叫做flightResult.html的页面生成了一段这样的代码提供给jsonp.html(服务端的实现这里就不演示了,与你选用的语言无关,说到底就是拼接字符串):
flightHandler({ "code": "CA1998", "price": 1780, "tickets": 5 });
我们看到,传递给flightHandler函数的是一个json,它描述了航班的基本信息。运行一下页面,成功弹出提示窗口,jsonp的执行全过程顺利完成!如下所示:
d.到这里为止的话,相信你已经能够理解jsonp的客户端实现原理了吧?剩下的就是如何把代码封装一下,以便于与用户界面交互,从而实现多次和重复调用。
当然,如你用的是jQuery,肯定也想知道jQuery如何实现jsonp调用?下面是一段jQuery使用jsonp的代码(我们依然沿用上面那个航班信息查询的例子,假定返回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>jquery jsonp</title> <script type="text/javascript" src="jquery-1.8.3.js"></script> <script type="text/javascript"> jQuery(document).ready(function(){ $.ajax({ type: "get", async: false, url: "http://127.0.0.1:8080/RemoteService/flightResult.html?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时(还是忍不住吐槽,虽然jquery也把jsonp归入了ajax,但其实它们真的不是一回事儿),自动帮你生成回调函数并把数据取出来供success属性方法来调用,是不是很爽呀?
PS:ajax与jsonp的异同的补充说明
1.ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;
2.但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。
3.所以说,其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。
4.还有就是,jsonp是一种方式或者说非强制性协议,如同ajax一样,它也不一定非要用json格式来传递数据,如果你愿意,字符串都行,只不过这样不利于用jsonp提供公开服务。
总而言之,jsonp不是ajax的一个特例,哪怕jquery等巨头把jsonp封装进了ajax,也不能改变着一点!
文章来源:http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html
相关推荐
内容概要:本文详细介绍了如何利用STM32和MATLAB实现倒立摆控制系统。首先,文章讲解了硬件部分,包括STM32F4作为主控、TB6612驱动直流电机以及MPU6050进行角度采集。接着,深入探讨了PID控制算法的应用,尤其是增量式PID算法及其参数调节方法。此外,文章强调了MATLAB Simulink仿真的重要性,展示了如何通过Simulink自动生成适用于STM32的嵌入式代码。最后,分享了一些实用技巧,如角度采集的互补滤波算法、PWM输出限幅、硬件设计注意事项等。 适合人群:对嵌入式系统和自动化控制感兴趣的电子工程师、机器人爱好者以及有一定编程基础的学习者。 使用场景及目标:①帮助读者理解并掌握倒立摆控制系统的原理和技术细节;②提供从理论到实践的具体步骤指导,便于读者复现实验;③培养解决实际问题的能力,提高对PID控制和其他相关技术的理解。 其他说明:文中提供了大量源代码片段和硬件设计建议,有助于读者更好地理解和实施项目。同时,作者还分享了许多个人经验和常见错误,使得初学者能够避开一些潜在的陷阱。
内容概要:本文详细介绍了使用组态王6.53构建多种液体混合仿真监控系统的过程。从系统概述出发,涵盖了工程建立、变量定义、画面创建、命令语言编写、监控与调试等多个方面。具体实现了液位监测、阀门控制、搅拌控制、报警处理等功能,并针对可能出现的问题如模拟量输入抖动、阀门死锁、电机启动电流冲击等提供了有效的解决方案。此外,还探讨了硬件配置、数据记录、性能优化等方面的内容,强调了系统稳定性的重要性和实际应用中的注意事项。 适用人群:从事工业自动化领域的工程师和技术人员,尤其是对组态王有一定了解或正在学习组态王的初学者。 使用场景及目标:适用于需要开发类似液体混合仿真监控系统的工程项目,旨在提高系统的稳定性和可靠性,减少故障发生率,提升生产效率。 其他说明:文中不仅提供了详细的步骤指导,还分享了许多作者在实践中积累的经验和技巧,对于理解和掌握组态王的应用具有很高的参考价值。
内容概要:本文详细介绍了双馈风力发电机(DFIG)采用直接功率控制(DPC)策略的Matlab/Simulink模型搭建过程。首先解释了DPC相对于传统矢量控制的优势,然后逐步讲解了模型各组成部分的搭建方法,包括风速模块、风力机模型、双馈发电机模型、变换器模型和直接功率控制器模块。文中还提供了具体的MATLAB代码示例,展示了如何实现风速模拟、功率计算、PI控制算法等功能。此外,文章强调了模型调试过程中需要注意的关键点,如坐标变换、采样频率、滞环宽度等,并分享了一些实用的经验技巧。 适合人群:从事风力发电研究的技术人员、高校相关专业师生、对电力电子控制系统有兴趣的学习者。 使用场景及目标:适用于希望深入了解DFIG运行机制及其控制策略的研究人员和技术开发者。通过构建和仿真该模型,能够更好地掌握DPC的工作原理,优化风力发电系统的性能,提高发电效率和稳定性。 其他说明:文章不仅提供了详细的理论背景介绍,还包括大量实用的操作指南和代码片段,帮助读者快速入门并在实践中不断改进和完善自己的模型。
内容概要:本文详细介绍了使用COMSOL进行三维摩擦发电机数值模拟的方法和技术要点。首先讨论了几何建模的具体步骤,包括使用布尔运算创建咬合结构以及调整电极尺寸。接下来深入探讨了电荷密度的设定方法,强调了自定义场函数的应用及其灵活性。随后讲解了电场分布的计算,特别指出自适应网格细化的重要性,并展示了不同材料组合对电荷密度和电场分布的影响。此外,文中还提到了一些常见的陷阱,如介电常数设置不当可能导致模型偏差,并提供了相应的解决办法。最后,作者分享了一些实用的经验和技巧,帮助提高模拟的准确性和效率。 适合人群:从事电磁学、材料科学或相关领域的研究人员和工程师,尤其是那些希望深入了解摩擦发电机工作机制的人。 使用场景及目标:适用于需要精确模拟和分析摩擦发电机性能的研究项目。主要目标是通过数值模拟优化电荷密度和电场分布,从而提高摩擦发电机的能量转换效率。 其他说明:文中不仅提供了详细的建模指导,还包括了许多实用的代码片段和注意事项,有助于读者更好地理解和应用所学知识。
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 Rust 以内存安全、零成本抽象和并发高效的特性,重塑编程体验。无需垃圾回收,却能通过所有权与借用检查机制杜绝空指针、数据竞争等隐患。从底层系统开发到 Web 服务构建,从物联网设备到高性能区块链,它凭借出色的性能和可靠性,成为开发者的全能利器。拥抱 Rust,解锁高效、安全编程新境界!
内容概要:本文详细探讨了基于能源集线器参数的电热综合能源市场双层出清模型的实现。首先介绍了综合能源系统及其重要组成部分——能源集线器的功能,即作为电、热等不同能源形式的转换和分配枢纽。接着展示了如何使用MATLAB进行参数初始化、上层优化目标计算以及下层市场出清的潮流计算简化。文中还重点讲解了CPLEX在处理双层模型中的作用,如将MPEC问题转化为MILP并通过KKT条件解决市场博弈问题。此外,通过实例演示了电热价差对储热量的影响,并讨论了蒙特卡洛模拟用于处理风光出力不确定性的方法。最后给出了求解器调用时需要注意的问题和调试技巧。 适合人群:从事能源系统研究的专业人士、研究生及以上学历的学生,尤其是那些对电热综合能源市场、能源集线器、MATLAB编程和优化算法感兴趣的人群。 使用场景及目标:适用于希望深入了解并掌握电热综合能源市场运作机制的研究人员和技术开发者。目标是帮助读者理解如何利用MATLAB和CPLEX构建高效的能源管理系统,从而提高能源利用率,降低运营成本。 其他说明:文中提供了大量实用的MATLAB代码片段,有助于读者快速上手实践。同时提醒读者在实际应用中应注意求解器参数配置等问题,确保模型的有效性和准确性。
中心锥锥角对涡喷发动机尾喷管气动性能影响规律研究.pdf
内容概要:本文探讨了如何利用MATLAB代码实现综合能源系统在碳交易机制和需求响应下的优化运行。首先介绍了需求响应模型的两种类型:价格型和替代型。价格型需求响应基于价格弹性矩阵,描述了能源价格变动对用户需求的影响;替代型需求响应则关注电能和热能之间的转换。接着讨论了碳交易机制的构建,包括碳排放量的计算和碳排放配额的分配方法。然后提出了综合能源系统的低碳优化运行模型,设定了购能成本、碳交易成本及运维成本之和最小为目标函数,并通过线性规划求解。最后,通过对四种典型场景的验证,展示了模型的有效性。 适合人群:从事综合能源系统研究的技术人员、研究生及以上学历的研究人员。 使用场景及目标:适用于希望深入了解综合能源系统优化运行机制的人群,尤其是希望通过MATLAB代码实现具体模型构建和技术验证的专业人士。目标是在满足多种约束条件下,实现综合能源系统的低碳优化运行,降低运营成本并有效管理碳排放。 阅读建议:由于涉及较多具体的MATLAB代码实现细节,建议读者具备一定的编程基础和相关领域的背景知识,以便更好地理解和应用文中提供的技术和方法。
内容概要:本文深入探讨了路径规划算法的研究进展,特别是对经典的蚁群算法进行了多项创新性的改进。作者详细介绍了如何利用Matlab实现蚁群算法的基本框架,并针对路径平滑度不足的问题提出了基于Flod算法的双向平滑度优化方法。此外,还自主研发了一种全新的路径规划算法,能够灵活应对不同的地图环境。通过对多种算法的实际性能对比,展示了改进后的蚁群算法在路径长度和平滑度方面的显著提升。 适合人群:对路径规划算法感兴趣的科研人员、工程师以及高校师生。 使用场景及目标:适用于需要高效、平滑路径规划的应用场合,如机器人导航、物流配送系统等。目标是为用户提供一种更为智能化、高效的路径解决方案。 其他说明:文中提供了详细的代码片段和技术细节,有助于读者理解和复现实验结果。同时,强调了算法在实际应用场景中的表现和潜在价值。
图书馆管理系统源代码.7z
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 Rust 以内存安全、零成本抽象和并发高效的特性,重塑编程体验。无需垃圾回收,却能通过所有权与借用检查机制杜绝空指针、数据竞争等隐患。从底层系统开发到 Web 服务构建,从物联网设备到高性能区块链,它凭借出色的性能和可靠性,成为开发者的全能利器。拥抱 Rust,解锁高效、安全编程新境界!
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 编译闪电般迅速,并发性能卓越,部署轻松简单!Go 语言以极简设计理念和出色工程性能,成为云原生时代的首选编程语言。从 Docker 到 Kubernetes,全球顶尖科技企业都在采用 Go。点击了解 Go 语言的核心优势、实战窍门和未来走向,开启高效编程的全新体验!
c++-信息解密-代码
没啥东西
数字集群通信系统综述.pdf
基于谓词逻辑的归结原理研究.pdf
文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 Rust 以内存安全、零成本抽象和并发高效的特性,重塑编程体验。无需垃圾回收,却能通过所有权与借用检查机制杜绝空指针、数据竞争等隐患。从底层系统开发到 Web 服务构建,从物联网设备到高性能区块链,它凭借出色的性能和可靠性,成为开发者的全能利器。拥抱 Rust,解锁高效、安全编程新境界!
内容概要:本文详细探讨了利用改进粒子群算法(MOPSO)解决分布式电源(DG)在配电网中的选址和定容问题。文中介绍了多目标优化的目标函数构建方法,如网损、投资成本和电压偏差的计算,并展示了如何通过动态惯性权重、随机扰动和拥挤度排序等手段提高算法性能。此外,文章还讨论了帕累托解集的维护和最终解的选择策略,强调了实际应用中的物理可行性和参数调优经验。 适合人群:从事电力系统规划、优化算法研究以及相关领域的工程师和技术人员。 使用场景及目标:适用于需要在配电网中合理配置分布式电源的实际工程项目,旨在降低网损、控制投资成本并维持电压稳定,从而提高电网的整体经济性和稳定性。 其他说明:文中提供了具体的代码实现和实际案例分析,帮助读者更好地理解和应用所介绍的方法。同时,作者指出,尽管算法能够提供多种平衡解,但在实际应用中还需结合具体情况进行选择。
Dify智能体:AI智能问数.yml
转向模型总成,反阿克曼转向模型 10 英寸方向盘 36 齿齿条 24 齿小齿轮