在前端使用 Date 对象获取当前时间的时候, 该时间是客户端的时间. 但是该时间可以被用户修改, 所以我们一般情况下并不想要这个时间. 如果每一次获取时间的时候都请求一下服务器, 那么将会对服务器造成不必要的压力, 我们也不想这么做. 在网上找了一圈之后, 发现了一些解决方案, 就在这里总结一下
1. 当系统被用户第一次打开的时候, 发送请求 (没必要写一个专门获取时间的 API), 根据 http 的相应头 Date 字段获取服务器时间. 此时与客户端时间做差, 并将差值记录下来.
2. 为了防止客户端时间被用户修改, 我们每隔 2s(这个自定义吧) 获取一下客户端时间, 并将上一个时间和当前时间做差, 看和 2s 差的大不大, 正常情况下也就是几十毫秒的差值, 我们在这里比方设为 1s. 如果差值大于 1s, 我们就认为客户端时间被修改了, 我们此时获取一下前一个时间和当前时间的差值再减去 2s 就是修改时候后的差值.
3.moment.JS 内部获取时间是使用的 moment.now 方法, 我们把这个方法自定义一下就可以了
以下是代码实现:
- var diff = 0; // 记录服务器和客户端的时间差值
- var lastTime; // 记录上一次时间
- $(function(){
- $.Ajax({
- url: apiURL,
- }).always(function(res, state, xhr){
- var serverTime = new Date(xhr.getResponseHeader("Date")).getTime();
- var localTime = +new Date;
- diff = serverTime - localTime;
- lastTime = localTime;
- var InvertialMillSeconds = 2000;
- var maxMillSeconds = 1000;
- // 每 InvertialSeconds 毫秒检测一次当前时间,
- // 若差值大于 maxMillSeconds 那么可以判断出客户端时间被修改了
- setTimeout(function(){
- var nowTime = +new Date;
- var InverDiff = nowTime - (lastTime + InvertialMillSeconds);
- if(Math.abs(InverDiff)> maxMillSeconds){
- diff += InverDiff;
- }
- lastTime = nowTime;
- setTimeout(arguments.callee, InvertialMillSeconds);
- }, InvertialMillSeconds);
- })
- })
moment.now 本来是这个样子的
- var now = function() {
- return Date.now ? Date.now() : +(new Date());
- };
我们在引入 moment.JS 之后, 重新修改该值为
- if (Windows.moment && Windows.moment.now) {
- moment.now = function(){
- return Date.now ? Date.now()+top.diff : (new Date().getTime() + top.diff);
- }
- }
到此, 大功告成!
来源: https://www.cnblogs.com/theone67/p/12050776.html