目录

前端如何在没有后端配合的情况下获取服务器时间

前端如何在没有后端配合的情况下获取服务器时间?

现在有一个需求,前端需要同步服务器的时间,因为前端的时间是不可靠的,解决方案有很多,但是不管什么方案,都是需要和服务端进行交互,那么怎么减轻后端的工作量直接实现呢?

HTTP Header 中的 Date

HTTP Header 中有一个字段叫做 Date,它的格式是 RFC 1123 ,也就是 Fri, 30 Sep 2022 02:30:19 GMT ,这个时间是服务器的时间,我们可以直接从 HTTP Header 中获取这个时间,然后前端直接使用这个时间即可。

打开控制台,查看一下请求的 HTTP Header,可以看到 Date 字段,这个就是服务器的时间:

https://i-blog.csdnimg.cn/blog_migrate/1362bb5ceb83b2bb613c343dd1f08e2a.png

这里有一个细节,可以看到这个时间的结尾有 GMT 的字母,代表这个时间是 GMT 时间,也就是格林威治时间,我们需要将这个时间转换成本地时间,因为我们前端的时间是本地时间,如果不转换,那么前端的时间就会和服务器的时间不一致。

https://i-blog.csdnimg.cn/blog_migrate/931d67834f71f6ceb570fb8586368a90.png

如上图,带了 GMT 的后缀的时间是ok的,不带的就需要转换了。

本地时间和 GMT 时间

我们知道,本地时间和 GMT 时间是有区别的,比如北京时间和 GMT 时间的区别是 8 小时,那么我们如何获取本地时间和 GMT 时间的区别呢?

const date = new Date()
const offset = date.getTimezoneOffset() // 480 

这里的 offset 就是本地时间和 GMT 时间的区别,单位是分钟,如果是北京时间,那么 offset 就是 480,如果是东京时间,那么 offset 就是 540。

本地时间和 GMT 时间的转换

我们知道了本地时间和 GMT 时间的区别,那么我们就可以将 GMT 时间转换成本地时间了,这里有一个小技巧,我们可以直接使用 new Date() 来转换,因为 new Date() 可以接受 GMT 格式的时间,然后会自动转换成本地时间。

const date = new Date('Fri, 30 Sep 2022 02:30:19 GMT')
console.log(date) // Fri Sep 30 2022 10:30:19 GMT+0800 (中国标准时间) 

这里我们可以看到, new Date() 接受了 GMT 格式的时间,然后自动转换成了本地时间。

前端实现

现在我们已经知道了如何获取服务器的时间,以及如何将 GMT 时间转换成本地时间,那么我们就可以实现前端获取服务器时间了。

axios.head('https://www.baidu.com?_=' + new Date().getTime()).then(res => {const date = new Date(res.headers.date)console.log(date) // Fri Sep 30 2022 10:30:19 GMT+0800 (中国标准时间)
}) 

这里使用 axios 发送一个 head 请求,然后获取 Date 字段,然后转换成本地时间,这样就可以获取到服务器的时间了,加时间戳是为了防止浏览器缓存。

优化

上面的代码是可以正常工作的,但是有一个问题,就是每次都要发送一个 head 请求,这样会增加服务器的压力,所以我们可以优化一下,比如我们可以在页面加载的时候就获取服务器的时间,然后每隔一段时间再获取一次,这样就可以减少服务器的压力了。

let date = new Date()
function getServerTime() {setTimeout(() => {axios.head('https://www.baidu.com?_=' + new Date().getTime()).then(res => {date = new Date(res.headers.date)console.log(date) // Fri Sep 30 2022 10:30:19 GMT+0800 (中国标准时间)}).finally(() => {getServerTime()})}, 1000 * 60 * 5)
}
getServerTime()

function timeStep(time) {date.setTime(date.getTime() + time)setTimeout(() => {timeStep(time)}, time)
}
timeStep(1000);

这里我们使用 setTimeout 来模拟服务器的时间,然后每隔一段时间就获取一次服务器的时间,这样就可以减少服务器的压力了。

总结

没啥好总结的,就是获取服务器的时间,然后转换成本地时间,然后模拟服务器的时间,这样就可以实现前端获取服务器时间了。

最后

最近找到一个 VUE 的文档,它将 VUE 的各个知识点进行了总结,整理成了《Vue 开发必须知道的 36 个技巧》。内容比较详实,对各个知识点的讲解也十分到位。

https://i-blog.csdnimg.cn/blog_migrate/f7b7a6e535a573b965ddecfe44f6e555.jpeg#pic_center

https://i-blog.csdnimg.cn/blog_migrate/7bb84306ea812daf388539c395953ba2.png#pic_center

https://i-blog.csdnimg.cn/blog_migrate/73af5fe1e890bf13e7b92a4458db5413.png#pic_center

https://i-blog.csdnimg.cn/blog_migrate/f5e692bb2e774b9be1dced5e193f0cf5.png#pic_center

有需要的小伙伴,可以点击下方卡片领取,无偿分享