日期:2014-05-16  浏览次数:20384 次

学习总结:前端跨域请求的解决办法——JSONP(很好)

学习总结:前端跨域请求的解决办法——JSONP

Web Ajax jQuery json jsonp ?

项目(打下广告,http://xin.taobao.com )当中碰到一个需求,涉及到前端跨域请求的问题,印象中有一种方法叫jsonp,之前听过但没有详细了解过,趁任务不多看了几篇相关的文档学习了一下,并做了下总结。

附件里包含了这篇文章的文档和两个可用实例。

1、Web2.0的趋势


内容的聚合,mashup

2、浏览器的限制


由于受到浏览器的限制,Ajax不允许跨域通信。如果尝试从不同的域请求数据,会出现安全错误。如果能控制数据驻留的远程服务器并且每个请求都前 往同一域,就可以避免这些安全错误。但是,如果仅停留在自己的服务器上,Web 应用程序还有什么用处呢?如果需要从多个第三方服务器收集数据时,又该怎么办?
说了那么多,根本意思就是通过ajax的形式去调用其他网站的接口是不行的。
例如:

Js代码 ?收藏代码
  1. $.ajax({??
  2. ??url:?"http://www.google.com/search?q=jquery" ,??
  3. ??success:?function (json){??
  4. ????alert(json.count)??
  5. ??}??
  6. });??

?

3、解决方法


为了在页面当中整合第三方服务器的数据,有那么几种方法:
1.克服该限制的一个相对简单的方法是让 Web 页面向它源自的 Web 服务器请求数据,并且让 Web 服务器像代理一样将请求转发给真正的第三方服务器。尽管该技术获得了普遍使用,但它是不可伸缩的。
我的理解:在后台代码中实现对第三方服务器的请求(API调用之类的),因为后台代码不受跨域限制。对其中所说的“不可伸缩”不太理解
2.另一种方式是使用框架要素在当前 Web 页面中创建新区域,并且使用 GET 请求获取任何第三方资源。不过,获取资源后,框架中的内容会受到同源策略的限制。
我的理解:就是使用iframe嵌套页面,但嵌套的页面同样会受到跨域的限制
3.第三种方法就是“JSONP”,全称是“JSON with Padding”,padding的中文意思是“填充”,之后我们会明白“填充”的意义。

4. JSONP原理


JSONP需要完成的任务包括两个方面:
? 获取第三方服务器上的数据;
? 通过本地的JS代码对第三方的数据进行处理和渲染

浏览器虽然限制了Ajax的跨域通信,但允许在页面中插入动态的脚本元素。简单的讲就是从第三方服务器加载js代码是可行的,例如:

Html代码 ?收藏代码
  1. < script ? type = "text/javascript" ? src = "http://www.google.com/test.js" > </ script > ??


注释:但加载的js代码同样被视作是从当前域加载的,所以想在第三方的js代码中进行对第三方服务器的ajax调用同样是不行的。

所以可以通过第三方服务器生成动态的js代码来回调本地的js方法,而方法中的参数则由第三方服务器在后台获取,并以JSON的形式填充到JS方法当中,这也就是“JSON with Padding”中“padding”的真正意义。

应用过程当中,请求方(本地)向第三方服务器请求动态JS脚本,并将获取数据后需要回调的函数名以约定好的参数名(如callback等)发送给第三方服务器。

第三方服务器需要为JSONP请求开发相应的API,API中先获取JSONP请求需要的数据,然后以JSON的形式封装,再与请求方的回调函数名拼接在一起,动态生成请求方需要调用的JS代码。
用 Java servlet 实现的 JSONP 服务示例代码如下:

Java代码 ?收藏代码
  1. protected ? void ?doGet(HttpServletRequest?req,?HttpServletResponse?resp)? throws ?ServletException,?IOException?{??
  2. //获取JSON数据 ??
  3. String?jsonData?=?getDataAsJson(req.getParameter(