AJAX、JSONP和CORS

学习了数据交互行为的时候了解了AJAX和JSONP。(JSONP和HTML5是“同时代”的,尽管它没有在HTML5规范中定义,但是在HTML5的应用中大量使用,它是构建Web应用的一个核心应用。)

运用AJAX进行数据交互就会不可避免的面临两个问题。第一个是AJAX以何种格式来交换数据?第二个是跨域的需求如何解决?

这两个问题都有不同的解决方案,数据可以用自定义字符串或者用XML来描述,跨域可以通过服务器端托管的代理来解决或者运用JSONP。
但到目前为止最被推崇或者说首选的方案还是用JSON来传数据,靠JSONP来跨域。而这就是本文主要讲述的内容。

AJAX
        AJAX使用 XMLHttpRequest异步函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器。Ajax 也是许多 mashup 的驱动力,它可将来自多个地方的内容集成为单一 Web 应用程序。
        不过,由于受到浏览器的限制,Ajax直接请求普通文件存在跨域无权限访的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准该方法跨域通信。如果尝试从不同的域请求数据,可以通过服务器端托管的代理来解决。如果能控制数 据驻留的远程服务器并且每个请求都前往同一域,就可以避免这些安全错误,这就是所谓的通过服务器端托管。
但是,如果仅停留在自己的服务器上,需要从多个第三方服务器收集数据时,又该怎么办?这个时候JAONP派上用场了!

JSON
        简单说了一下,JSON是一种基于文本的数据交换方式,或者叫做数据描述格式。
        我们知道Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>);
       
        于是可以判断,当前阶段如果想通过纯web端(ActiveX控件、服务端代理、属于未来的HTML5之Websocket等方式不算)跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理;

        恰巧JSON的纯字符数据格式可以简洁的描述复杂数据,更妙的是JSON还被js原生支持,所以在客户端几乎可以随心所欲的处理这种格式的数据;
这样子解决方案就呼之欲出了,web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。

        客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了。如何处理JSON数据呢?
为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP。该协议的一个要点就是允许用户传递一个回调函数callback给服务端,然后服务端返回数据时会将这个callback函数来包裹住JSON数据,解析JSON的时候,JSON被包装成一个Javascript对象了。

        AJAX和JSONP这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把JSONP作为AJAX的一种形式进行了封装;
但AJAX和JSONP其实本质上是不同的东西。AJAX的核心是通过XmlHttpRequest获取非本页内容,直接返回的数据是字符串表示,而JSONP的核心则是动态添加<script>标签来调用服务器提供的js脚本,返回的是经过回调函数callback包裹的对象。
所以说,其实AJAX与JSONP的区别不在于是否跨域,AJAX通过服务端代理一样可以实现跨域,JSONP本身也不排斥同域的数据的获取。

JSONP看上去貌似一个安全漏洞,如果向一个恶意的Web服务发出一个JSONP请求,响应中可能包含我们不想要的javascript代码,而且浏览器还会执行这些恶意的代码,但是这与链接其他服务器上的托管的库来包含javascript没有什么两样,是要链接了javascript都需要使用JSONP,都需要确保信任这个服务。
如果要编写一个Web应用,其中使用认证来授权用户的访问敏感数据,可能最好的办法就是不要使用第三方库或位于其他服务器的JSONP了。所以要谨慎选择所链接的Web服务。


CORS(跨域资源共享,Cross-Origin Resource Sharing)
        可是如果某天PM的需求变了,某功能需要改成支持POST,因为传输的数据量比较大,GET形式搞不定(要知道JSONP是通过“GET”形式来搞的,其承载的信息量有限,所以信息量较大时CORS是不二选择。
        跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。 它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。简言之,CORS就是为了让AJAX可以实现可控的跨域访问而生的。
        假设我们页面或者应用已在 http://www.test1.com 上了,而我们打算从 http://www.test2.com 请求提取数据。利用 CORS,http://www.test2.com 只需添加一个标头,就可以允许来自 http://www.test1.com 的请求,下图是在PHP中的 hander() 设置,“*”号表示允许任何域向我们的服务端提交请求:

也可以设置指定的域名,如域名 http://www.test2.com ,那么就允许来自这个域名的请求:

         当前设置的header为“*”,任意一个请求过来之后服务端我们都可以进行处理&响应,那么在调试工具中可以看到其头信息设置,其中见红框中有一项信息是“Access-Control-Allow-Origin:* ”,表示我们已经启用CORS,当然,如果没有开启CORS必定失败的。

   cors在移动终端支持的不错,可以考虑在移动端全面尝试;PC上有不兼容和没有完美支持,所以小心踩坑。当然浏览器兼容就是个伪命题,说不准某个浏览器的某个版本就完美兼容了,说不准就有点小坑。
    jsonp是get形式,承载的信息量有限,所以信息量较大时CORS是不二选择;
    配合新的JSAPI(fileapi、xhr2等)一起使用,实现强大的新体验功能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值