Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chenzx/0803db155fbe002454a8 to your computer and use it in GitHub Desktop.
Save chenzx/0803db155fbe002454a8 to your computer and use it in GitHub Desktop.
浏览器新实用功能开发研究:单页富客户端应用的会话/视图状态复制及远程同步功能
浏览器新实用功能开发研究:单页富客户端应用的会话/视图状态复制及远程同步功能
目录
1 一个简单的使用场景
2 单页(富客户端)应用的会话/视图状态表示
3 状态复制及远程同步
4 SPA情景下的Web Cache变化
一个简单的使用场景
我之前成功地在3台机器上使用Google OAuth账户登陆过feedly,不幸的是,后来Google的账号登陆地址被gfw封了,所以我没办法在新电脑上进入我的feedly,值得庆幸的是,feedly始终缓存了我的登陆凭据(不知道是不是用Cookie表示的?),所以要是多刷新几次,在老的那3台电脑上仍然能够使用feedly。
实际上,feedly就是一个单页富客户端应用的例子,它在每次打开时先下载一个html文件,然后html需要加载4个压缩过的js文件,总计2MB的数据量,如果这4个js被gfw暂时屏蔽的话,页面将无法成功打开。我在想这里feedly为什么不把这4个js文件做成每个URL地址无限缓存,如果需要新版本的js的话,就在这4个js URL上加个版本id号,——这样不是很好吗?
所以,作为客户端的浏览器,我们要解决的第一个问题是:如何在另外一台全新的电脑上恢复你之前已经登陆过的单页应用(SPA)的视图/会话状态???
单页(富客户端)应用的会话/视图状态表示
首先,我们考虑所谓的视图会话状态究竟指的是什么?
视图状态 它包含用JS通过Ajax请求得到的Web服务响应JSON数据以及动态构造出来的DOM树、frame的滚动位置,等等
会话状态 SPA可能需要登陆使用(当然,如果没有隐私敏感数据的话,Web SPA应该做成无需登陆的),会话在当前的浏览器架构上仍然使用Cookie表示,不过理论上也有可能使用其他“高端”技术:
HTTP 1.1 ETag
浏览器特征指纹
HTML5 Application Cache/Local Storage
状态复制及远程同步
只考虑最简单的cookie,不考虑所谓的视图状态复制恢复,那么一个最简单可行的方法就是使用一个云端的中转服务器,(PS一下:现在的浏览器产商只实现了书签收藏夹的同步,这个也太原始了!),配套以客户端的Cookie导出导入功能就行了
此方案实现上应该是可行的,如果需要额外的视图滚动位置什么的,顶多加一段JS #hashtag定位代码。
但是、但是,这个技术方案的缺点就是不够通用,有没有更高端的方案?
有,但是实现起来比较困难:实现把SPA的内存DOM树完全序列化,保存到云端服务器,然后需要的时候在需要的时候在进行反序列化,这里有很多技术难点:
序列化采用那种方案?是序列化为HTML代码吗?那样的话,反序列化将需要定制特殊的ResourceLoader逻辑,有没有可能做到直接的内存复制?传统的直接内存复制实际上要求CPU体系结构保持一致,以避免大小端及其他的一些问题,如何做异构CPU之间的“直接内存复制”呢?
序列化后的数据量可能很大,有没有可能压缩数据量呢?UC/Opera的Web网页转码加速实际上就是这种用例,但那主要是为了减少移动用户的数据传输量、适应低端手机设备的上网需求的;有没有可能做到在不影响用户可用性情况下的部分序列化(并配套以延迟加载技术)?
好吧,暂时先谈这么多
SPA情景下的Web Cache变化
传统的HTTP Cache规范中,被缓存的资源实际上是以URL全局缓存的,这么做可能没有问题,但总感觉哪里有安全漏洞:我通过URL A加载了URL B、C、D的内容,这里请求B、C、D时根据HTTP规范需要将Referer设置为A,对B、C、D的服务器端而言,它完全可能根据Referer的不同返回不同的数据,虽然理论上来说,根据HTTP的原始初衷,或者说REST规范,不应该这么做。这时候假如访问URL E加载了D、F的内容,D被A、E源页面共同引用,D在目前的实际使用中可能是CDN托管的图像或JS库,当然也有可能是一个嵌入式的iframe广告。
在前面分析的SPA情景下,我们可以看到,HTTP Cache把URL作为全局缓存的key是不合适的,我们应该为A、E这2个不同的源html文档缓存2份D!暂且把这种新的客户端缓存方案称为Web Cache,这个方案的麻烦之处在于,这个缓存可能是级联的,现有的浏览器实际上没有处理好这种情况,导致一堆CSRF安全漏洞。
不考虑CSRF问题,Web Cache可能是级联的、嵌套依赖层次很深的缓存,但是在HTTP Cache方案下,这些后续的动态内容加载可能都是标记为不可缓存的,Web广告商实际上就要求这个,但是我觉得他们可以采取其他更好的手段,以避免吞啮过多的Internet流量。
浏览器产商可能不愿意开发这样的触动广告商利益的Web Cache本地层次化聚类缓存方案,但是最终用户也许需要这样的方案。。。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment