前端异步通信方式的发展历程
文中所列通信方式皆基于HTTP协议,请知悉!
传统
我们知道,在异步通信未诞生之前,前端与服务器的数据交互是这样的:读取-顺序读取本页面所有数据;提价-以表单形式来进行提交,服务器接收存储。这个过程中不仅会传输许多无用的数据,加大服务器的流量,在用户体验上也很死板,缺少与用户的交互。这种笨重的通信方式,亟待解决。
ajax诞生
2005年2月,Adaptive Path公司的Jesse James Garrett在网上发表了一篇名为《Ajax:一种Web应用程序开发的新方法》的文章(现在还可以在www.adaptivepath.com/publications/ essays/ archives/000385.php看到)。在这篇文章中,Garrett阐述了他为什么认为Web应用程序正在填平与传统桌面应用程序之间的鸿沟。他引用了一些新的技术,并以几个Google的项目作为例子,说明了如何将传统的、基于桌面应用程序的用户交互模型应用到Web上。然后他说出了两句引起人们大量兴趣、兴奋和争论的话:
Google Suggest和Google Maps就是这种新型Web应用程序的两个例子,在Adaptive Path公司里,我们将这种理念称为 Ajax。这是Asynchronous(异步)JavaScript + XML的简写,它预示着Web可能将发生一次根本性的变革。
从此之后,关于Ajax的文章、示例代码以及争议有如潮水一般充斥于整个因特网上。开发人员在Blog上谈到它,技术杂志关注它,而许多公司则在产品中应用它,市场需求带动了发展,ajax应运而生。
ajax的详细介绍建议阅读《AJAX工作原理及其优缺点》
新兴一代:Jsonp
长江后浪推前浪,一代更比一代强. 由于ajax被同域限制着, 导致多服务器配置,云服务资源的存储等跨域请求的应用没办法充分利用.
所以,业界想到另外一种方法–JSONP.
JSONP实际上和ajax没有半点关系,唯一相同的就是都是异步执行,而且JSONP完美解决了CD(cross domain)问题。然而,矛盾无处不在,jsonp也有他的缺点:
-
它只支持GET请求而不支持POST等其它类型的HTTP请求
-
它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
-
jsonp在调用失败的时候不会返回各种HTTP状态码。
-
缺点是安全性。万一假如提供jsonp的服务存在页面注入漏洞,即它返回的javascript的内容被人控制的。那么结果是什么?所有调用这个
jsonp的网站都会存在漏洞。于是无法把危险控制在一个域名下…所以在使用jsonp的时候必须要保证使用的jsonp服务必须是安全可信的。
太平盛世
这两个难兄难弟在解决前端异步通信问题中相辅相成,携手并进。现今仍活跃在前端开发技术的大潮中。大多数浏览器都有对他们的支持,许多第三方工具库为他们也提供了支持,比如jquery,值得乐道的是,jquery在封装过程中,由于将ajax和jsonp放在了一起,并命名为$.ajax,使得jsonp显得光彩暗淡,也让人对ajax和jsonp傻傻分不清楚(其实两者技能差别挺大的)。
发展趋势
2015 年 6 月,ECMAScript 6 的正式版 发布。ES6 原生提供了 Promise 对象。为了提供更加强大、高效的网络请求,Fetch诞生,Fetch是基于Promise一个新的,有很好的发展趋势的异步通信技术,由于只有部分浏览器支持,所以还没有得到广泛使用。更多Fetch的详细信息可参阅:《Fetch进阶指南》
最近在学习angualr2,在学习到http请求这个章节时,文中提到基于promise异步通信有一个缺点,并给出了一个新的解决方案:Observable
,,原文如下:
************************************************************************************************
Http
服务中的每个方法都返回一个 HTTP Response
对象的Observable
实例。
我们的HeroService
中把那个Observable
对象转换成了Promise
(承诺),并把这个承诺返回给了调用者。
这一节,我们将学会直接返回Observable
,并且讨论何时以及为何那样做会更好。
一个可观察对象是一个事件流,我们可以用数组型操作符来处理它。
Angular 内核中提供了对可观察对象的基本支持。而我们这些开发人员可以自己从 RxJS 库中引入操作符和扩展。
我们会简短的讲解下如何做。
快速回忆一下HeroService
,它在http.get()
返回的Observable
后面串联了一个toPromise
操作符。
该操作符把Observable
转换成了Promise
,并且我们把那个承诺返回给了调用者。
转换成承诺通常是更好地选择,我们通常会要求http.get()
获取单块数据。只要接收到数据,就算完成。
使用承诺这种形式的结果是让调用方更容易写,并且承诺已经在 JavaScript 程序员中被广泛接受了。
但是请求并非总是“一次性”的。我们可以开始一个请求,
并且取消它,在服务器对第一个请求作出回应之前,再开始另一个不同的请求 。
像这样一个请求-取消-新请求的序列用承诺是很难实现的,但接下来我们会看到,它对于可观察对象却很简单。
请求-取消-新请求的序列对于Promise
来说是很难实现的,但是对Observable
来说则很容易。
************************************************************************************************