Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

不诚实的 Date

  在前端开发中,我们通常会使用 JavaScript 的 Date 对象来取当前时间,很少有人去怀疑它的准确性。但浏览器上的 Date 对象只是根据系统时间来取值的,它的值是不可靠的。在一些对于浏览器上需要精确到秒的业务中(比如秒杀)就要谨慎使用,以免出现奇怪的问题。

黑历史

  很久以前我也曾纠结过这个问题,当时还在搞 ASP,解决方法是直接在 HTML 元素上添加服务器的时间戳作为其属性。那么问题就来了,以这种方式解决会导致页面的 ETag 失效,或者会因为页面有开启 Cache 而得到旧的时间戳。不过当时确实没有开启 Cache,那时候我也不懂 ETag 之类的东西,所以就那么迷迷糊糊地解决了这个问题(对接手那个程序的开发者我只能说抱歉了)。

获取服务器时间

  服务器的时间要比客户端的时间可靠,而客户端获取准确时间的唯一途径就是请求服务器。其实当时解决的思路并没问题,只是用错了地方。不该在 HTML 里面写一个实时变化的东西。让客户端在响应头中获取时间才是正确的做法。但即便这么做,Cache 的问题依然也无法解决。比如存在一个绝对 Cache 的页面,浏览器只有首次访问时加载这个页面,之后就再也不发起请求了。不过好在需要精确时间业务通常不会搞出那么蛋疼的页面,即便 HTML 部分是绝对 Cache 的,也会有大量的 API 请求发起。所以只要有任何一个请求,我们都能通过请求的响应头来获取到服务器时间(但要小心跨域问题)。那么获取服务器时间的问题就基本解决了。

使用获取到的时间

  即便获取到一个准确的时间,又要如何使用它呢?每次调用 Date 时都去处理?或者封装成一个 getNow 之类的东西?其实都可以,八仙过海各显神通嘛。其实还可以直接劫持 Date 对象,将它获取当前时间的方式全部改为以从服务器获取到时间开始流逝的时间,这样即使 Date 对象被第三方插件使用也不必去改其代码。但毕竟是劫持原生,属于黑魔法系列,一定要慎用。

更深刻的问题

  既然都做到劫持原生这个份上了,于是我又想到了一个更深刻的问题。为什么 DOM 里没有一个可以设置当前时间起点的属性呢?要是有一个 document.setCurrentDate 之类的方法不就万无一失了么。也许是需求太少的缘故吧。反正我是挺希望有这么一个东西的,或者是已经有了只是我没找到?要是有的话真心求分享呐!

网名:
3.84.186.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^