Hybrid架构下,加载本地H5资源后,如何处理Ajax请求?

希望在app中打开H5页面能达到Native那样的速度,当然感觉不太可能,但两者速度越接近越好。 网上查了资料,有种方法是将网页资源嵌入到app中,打开时相当于加载本地资源。 参考:阿里巴巴(中国站)用户体验设计部博客 里面有段是这么描述的: 别忘了,我们是 Hybrid App,还可以充分利用 Native 层的强大能力,所以抛弃mainfest吧,让 Native 来帮助 Html5 应用缓存静态资源文件。总体思路是:1、Html5 应用首次启动时,调用 Na…
关注者
684
被浏览
12133
很荣幸在淘宝旅行时接触过类似的技术方案,简单回答一下题主提到的几个问题:

首先,什么是“虚拟域”?
直接上图吧:



既然要做资源离线化,肯定要把所有的资源请求到发到本地。

题主引用的 1688 那篇博客,里面提到“使用 Device API”来请求本地资源。我猜测他其实说的是 FileSystem API(这货其实在 2010 年时已经从 Device API 工作组移入了 Web Application 工作组)或者是 Native 通过 JS Bridge 暴露出来的 Hybrid API。
我个人觉得这样其实是有缺陷的 —— 如果你的资源请求都是通过 API “硬编码”来请求,那这货很明显在浏览器里跑不起来,当然,封装一层 Wrapper 兼容掉也行。

不小心吐槽太多了……那么淘宝旅行采用的是什么方案呢?

由于我们有大量现有的 codebase,不可能手动去替换各种 script, link 标签。可是这些标签请求的都是 taobao.com 域下的在线资源,Native App 本地里显然没有这个“域”(准确的说应该是 Domain Name),我们对着本地 IO 请求 taobao.com 肯定什么都拿不到。所以“虚拟域”就来了,为了让一套 web 页面同时兼容浏览器和 Hybrid 容器等多种环境,我们希望不改变前端代码就可以做到“资源请求发到本地”。所以说白了“虚拟域”无非就是让 Native 认得这个域名而已,这样 Native 容器里好像就有了域一样。



Native 认得域名了,就可以把该域下的请求转发到本地去拿。那么问题来了,Native 怎么知道哪些请求是需要被代理的,哪些又是不要的呢?
题主提到了一个方案是跨域,比如说我们只代理 A 域不代理 B 域,听上去好像是可行的,不过感觉还是不够 scale。其实我们使用的方案更简单粗暴一些,遍历一下文件目录生成一个映射表就好了,这里的虚拟域代理起到一个反向代理的作用,看一下 match 不 match 就知道该代理到哪去了。


映射表的生成直接做在持续集成的流程里,构建工具在 build 时会帮你生成出来,DX(开发者体验)非常的轻松且愉快,感谢工具小哥。


基本上就是这样。本来只想简单说下,洋洋洒洒也写了不少……
你问我这些牛逼的图都是哪来的?我当然不会把内部的东西随便乱发啦。
这些资源都是公开的,来自老大 @拔赤 在 2015 Qcon 的演讲 《极致的 Hybrid》,另外牛逼的工具小哥 @dickeylth 在 2014 D2 上也演讲过这个话题~(欢迎两位大大补充和指正)
完整的 PPT 在此:极致的Hybrid-Con2015.pdf


最后,帮老东家和现东家都低调得打个小广告:
阿里旅行-去啊 / 微信电影票长期招募前端开发高手加入,有志者邮件简历 bachi[at]taobao.com / huangxuan[at]wepiao.com

以上~