JSONP的应用
先前因为没工作需要,不存在需要跨域访问的应用,一直没接触过JSONP,只是了解个大概意思,即是插入一个SCRIPT标签,设置src,让浏览器加载并自动运行,但具体怎么过程,有什么常见的约定等等不甚了解,今天有机会接触了,具体说一下.
1. 其实JSONP也是一个”hack”应用
由于以前的应用没现在这么复杂,跨域访问浏览器端没提供标准的方法(可能那时还根本没考虑过..),当各种应用不断的丰富之后,需求也随之而来了,既然需求来了,但浏览器没提供直接的实现,此时就只能根据已有功能,玩些雕虫小技,待转几个弯,兜几个圈之后,JSONP就出来了.
2. hack的背后实现
浏览器加载标签的静态资源是可以跨域访问的,如常见的 link:href, script:src,img:src等等,没有安全限制,可直接访问,JSONP正是利用了这个特点,加载不同域上的脚本文件.
待把脚本script标签插入DOM上的head标签内,并设置好src属性时,浏览器就开始加载脚本,脚本下载完后直接运行返回的文本内容.
3. 我们需要的是数据而非源码
hack的过程已经了解,但目前为止作用不大,因为浏览器连接返回后获得资源就是JavaScript源码,并会立即执行这些源码,你无法异想天开的将这文本放到一个可控的eval里运行之后获得结果.假如这源码是任意的,那运行过程根本无法控制,而我们需要的是数据,而非源码!
要想控制这些源码,获得脚本运行的控制权,把源码转换成我们需要的数据,就得有个约定.
4. 普遍的相关约定
既然浏览器一定会自动执行返回的脚本这个客观事实改变不了,我们可以在返回的文本上做点处理,和服务器端作个约定,把个已在存在的回调函数写在外面,再把数据当作参数传递,当浏览器运行返回源码的时候,将调用这个回调函数,这样,控制权又从浏览器传回到我们的手中,数据即参数,也有了,可以为所欲为.
这过程中回调函数的名称是要确定的,通常是在发起前把回调函数名称以提交参数的形式写在URL中,服务器再从提交参数中把这回调函数名称输出到客户端.
如,存在一个全局回调函数 function jsonp_callback(data){ alert(data.a); }
发起时 : jsonp.connect(‘http://www.example.com/getdata.php?callback=jsonp_callback’);
//
在服务器端发现这个callback参数值为jsonp_callback,将输出类似的文本
jsonp_callback( /**数据*/{a:’b'} );
浏览器端请求返回后将立即运行 jsonp_callback( /**数据*/{a:’b'} );