原文出处: 小胡子哥的博客(@Barret李靖) php
先后端分工协做是一个老生常谈的大话题,不少公司都在尝试用工程化的方式去提高先后端之间交流的效率,下降沟通成本,而且也开发了大量的工具。可是几乎没有一种方式是令双方都很满意的。事实上,也不可能让全部人都满意。根本缘由仍是先后端之间的交集不够大,交流的核心每每只限于接口及接口往外扩散的一部分。这也是为何不少公司在招聘的时候但愿前端人员熟练掌握一门后台语言,后端同窗了解前端的相关知识。css
1、开发流程前端
前端切完图,处理好接口信息,接着就是把静态demo交给后台去拼接,这是通常的流程。这种流程存在不少的缺陷。ajax
后端同窗对文件进行拆分拼接的时候,因为对前端知识不熟悉,可能会搞出一堆bug,到最后又须要前端同窗帮助分析缘由,而前端同窗又不是特别了解后端使用的模板,形成尴尬的局面。数据库
若是前端没有使用统一化的文件夹结构,而且静态资源(如图片,css,js等)没有剥离出来放到 CDN,而是使用相对路径去引用,当后端同窗须要对静态资源做相关配置时,又得修改各个link,script标签的src属性,容易出错。json
接口问题
后端数据没有准备好,前端须要本身模拟一套,成本高,若是后期接口有改变,本身模拟的那套数据又不行了。后端
后端数据已经开发好,接口也准备好了,本地须要代理线上数据进行测试。这里有两个费神的地方,一是须要代理,不然可能跨域,二是接口信息若是改动,后期接你项目的人须要改你的代码,麻烦。api
不方便控制输出。为了让首屏加载速度快一点,咱们指望后端先吐出一点数据,剩下的才去 ajax 渲染,但让后端吐出多少数据,咱们很差控。跨域
固然,存在的问题远不止上面枚举的这些,这种传统的方式实在是不酷(Kimi 附身^_^)。还有一种开发流程,SPA(single page application),先后端职责至关清晰,后端给我接口,我所有用 ajax 异步请求,这种方式,在现代浏览器中可使用 PJAX 稍微提升体验,Facebook 早在三四年前对这种 SPA 的模式提出了一套解决方案,quickling+bigpipe,解决了 SEO 以及数据吐出过慢的问题。他的缺点也是十分明显的:浏览器
页面过重,前端渲染工做量也大
首屏仍是慢
先后端模板复用不了
SEO 依然很狗血(quickling 架构成本高)
history 管理麻烦
问题多的已是无力吐槽了,固然他依然有本身的优点,我们也不能一票否决。
针对上面看到的问题,如今也有一些团队在尝试先后端之间加一个中间层(好比淘宝UED的 MidWay )。这个中间层由前端来控制。
JavaScript +----------------+ | F2E | +---↑--------↑---+ | | +---↓--------↓---+ | Middle | +---↑--------↑---+ | | +---↓--------↓---+ | R2E | +----------------+ +----------------+ | F2E | +---↑--------↑---+ | | +---↓--------↓---+ | Middle | +---↑--------↑---+ | | +---↓--------↓---+ | R2E | +----------------+
中间层的做用就是为了更好的控制数据的输出,若是用MVC模型去分析这个接口,R2E(后端)只负责 M(数据) 这部分,Middle(中间层)处理数据的呈现(包括 V 和 C)。淘宝UED有不少相似的文章,这里不赘述。
2、核心问题
上面提出了在业务中看到的常见的三种模式,问题的核心就是数据交给谁去处理。数据交给后台处理,这是模式一,数据交给前端处理,这是模式二,数据交给前端分层处理,这是模式三。三种模式没有优劣之分,其使用仍是得看具体场景。
既然都是数据的问题,数据从哪里来?这个问题又回到了接口。
接口文档由谁来撰写和维护?
接口信息的改动如何向先后端传递?
如何根据接口规范拿到先后端可用的测试数据?
使用哪一种接口?JSON,JSONP?
JSONP 的安全性问题如何处理?
这一系列的问题一直困扰着奋战在前线的前端工程师和后端开发者。淘宝团队作了两套接口文档的维护工具,IMS以及DIP,不知道有没有对外开放,两个东西都是基于 JSON Schema 的一个尝试,各有优劣。JSON Schema 是对 JSON 的一个规范,相似咱们在数据库中建立表同样,对每一个字段作一些限制,这里也是同样的原理,能够对字段进行描述,设置类型,限制字段属性等。
接口文档这个事情,使用 JSON Schema 能够自动化生产,因此只需编写 JSON Schema 而不存在维护问题,在写好的 Schema 中多加些限制性的参数,咱们就能够直接根据 Schema 生成 mock(测试) 数据。
mock 数据的外部调用,这却是很好处理:
JavaScript
typeof callback === "function" && callback({ json: "jsonContent" }) typeof callback === "function" && callback({ json: "jsonContent" })
在请求的参数中加入 callback 参数,如 /mock/hashString?cb=callback,通常的 io(ajax) 库都对异步数据获取作了封装,咱们在测试的时候使用 jsonp,回头上线,将 dataType 改为 json 就好了。
JavaScript IO({ url: "http://barretlee.com", dataType: "jsonp", //json success: function(){} }) IO({ url: "http://barretlee.com", dataType: "jsonp", //json success: function(){} })
这里略微麻烦的是 POST 方法,jsonp 只能使用 get 方式插入 script 节点去请求数据,可是 POST,只能呵呵了。
这里的处理也有多重方式能够参考:
修改 Hosts,让 mock 的域名指向开发域名
mock 设置 header 响应头,Access-Allow-Origin-Control
对于如何拿到跨域的接口信息,我也给出几个参考方案:
fiddler 替换包,好像是支持正则的,感兴趣的能够研究下(求分享研究结果,由于我没找到正则的设置位置)
使用 HTTPX 或者其余代理工具,原理和 fiddler 相似,不过可视化效果(体验)要好不少,毕竟人家是专门作代理用的。
本身写一段脚本代理,也就是本地开一个代理服务器,这里须要考虑端口的占用问题。其实我不推荐监听端口,一个比较不错的方案是本地请求所有指向一个脚本文件,而后脚本转发URL,如:
JavaScript
原始请求:http://barretlee.com/api/test...
在ajax请求的时候:
$.ajax({ url: "http://<local>/api.php?path=/api/text.json" }); 原始请求:http://barretlee.com/api/test.json 在ajax请求的时候: $.ajax({ url: "http://<local>/api.php?path=/api/text.json" }); php中处理就比较简单啦: JavaScript if(!isset($_GET["page"])){ echo 0; exit(); } echo file_get_contents($_GET["path"]); if(!isset($_GET["page"])){ echo 0; exit(); } echo file_get_contents($_GET["path"]);
Ctrl+S,保存把线上的接口数据到本地的api文件夹吧-_-||
3、小结
本文只是对先后端协做存在的问题和现有的几种常见模式作了简要的列举,JSON Schema 具体如何去运用,还有接口的维护问题、接口信息的获取问题没有具体阐述,这个后续有时间会整理下我对他的理解。