前端保存一个版本

每次请求响应头带一个,这样也可以

先面试通过前端页面判断的

https://github.com/JoeshuTT/version-polling

https://github.com/jianxiaoBai/remote-file-monitor

1.需求分析

通常前端项目经开发迭代需求或者临时修复bug而上线后,我们都希望用户端能迅速检测项目已更新而去刷新页面。检测项目跟新的方法有很多,我这里提供一个适用度较高的简单易行的方法。

2.代码示例及分析

先直接贴源码:

// 用于记录时间戳的变量,时间戳是响应头中的etag和last-modified字段其中之一
let previousTimeTag

(async function () {
    // 通过立即执行函数,记录首次请求的时间戳,以便与后面轮询得出的时间戳进行对比
    previousTimeTag = await getTimeTag()
    window.versionMonitor&&clearInterval(window.versionMonitor)
    // 开启轮询执行judge函数
    window.versionMonitor = setInterval(() => {
        judge()
    }, 60 * 1000)
}())

async function getTimeTag () {
    const response = await fetch(`${window.location.protocol}//${window.location.host}`, {
        method: 'HEAD',
        cache: 'no-cache'
    })
    // 以响应体的etag或者last-modified为时间戳
    return response.headers.get('etag') || response.headers.get('last-modified')
}

async function judge () {
    // 获取当前最新的时间戳
    const currentTimeTag = await getTimeTag()
    // 检测到最新请求的时间戳和上一次不一致,即文件发生变化
    if (previousTimeTag !== currentTimeTag) {
        // 这里编写更新逻辑
    }
}

其实逻辑非常简单,就是在记录首次请求时协商缓存中的etag或者last-modified作为最先的时间戳previousTimeTag,然后轮询请求同样的地址获取最新的时间戳currentTimeTag。如果previousTimeTagcurrentTimeTag不一致,执行刷新提示逻辑。流程图如下所示:

缺陷:如果服务器禁止协商缓存,那就没办法使用该方法了。

3.代码细节分析

1.etag和last-modified

两者都是响应头中记录关于协商缓存的字段。

etag是与Web资源关联的记号(token),可以理解是对应Web资源的内容生成的hash码。如果两份Web资源的内容不一致,生成的etag也不一致。属于HTTP1.1的字段。

last-modified用于记录Web资源的最后修改时间。属于HTTP1.0的字段。