在 Web 中判断页面是不是刷新

news2024/9/24 1:22:05

在 Web 开发中,我们经常需要区分用户是否通过刷新操作重新加载了页面。这一操作可能是由用户手动刷新(如按下 F5 键或点击浏览器刷新按钮)或通过浏览器自动重新加载。判断页面是否刷新有助于开发者优化用户体验,例如在使用 vue 的时候需要进行权限控制,就需要判断在刷新后根据登录者的权限去添加对应的路由。

本文将详细解析几种常见的判断页面是否刷新的技术方案,并探讨各自的适用场景、优缺点以及浏览器的兼容性。

1. 使用 window.name

window.name 是一个持久的窗口属性,它的值在页面刷新、甚至通过标签页导航到其他页面时也会保留,因此可以利用它来判断页面是否是通过刷新重新加载。

代码示例

window.onload = function() {
  if (window.name === 'isRefreshed') {
    console.log('页面被刷新');
  } else {
    console.log('首次加载页面');
    window.name = 'isRefreshed';
  }
};

工作原理

  • 首次加载时,window.name 是空字符串,通过设置它为 'isRefreshed' 来标记状态。
  • 刷新页面后,window.name 仍保持为 'isRefreshed',因此可以判断页面是通过刷新加载的。

优点

  • 简单易用:不依赖外部存储机制或服务器端逻辑。
  • 跨页面持久性:在页面间导航时,window.name 的值依然保持,适合跨页面场景。

缺点

  • 安全性问题window.name 的值在不同页面间共享,可能被其他页面读取。
  • 手动清理:在某些场景下可能需要手动清除 window.name,例如页面关闭时。

兼容性

window.name 是一个非常老的 Web API,几乎在所有浏览器中都有广泛的支持,包括:

2. 使用 sessionStorage

sessionStorage 是 Web 存储 API 的一部分,它为每个标签页维护独立的存储空间,并且其数据在标签页关闭后会被清空。我们可以利用 sessionStorage 来判断页面是否被刷新:

window.onload = function() {
  if (sessionStorage.getItem('isRefreshed')) {
    console.log('页面被刷新');
  } else {
    console.log('首次加载页面');
  }
  sessionStorage.setItem('isRefreshed', true);
};

工作原理

  • 当页面首次加载时,sessionStorage 中没有 isRefreshed 条目,因此可以判断这是首次加载。
  • 通过设置 sessionStorage.setItem('isRefreshed', true);,标记页面已加载。
  • 当页面刷新后,sessionStorage 中的 isRefreshed 条目依然存在,因此可以检测到页面的刷新操作。

优点

  • 简单且不依赖服务器端逻辑。
  • 只对当前标签页有效,适合单个页面或 SPA(单页应用)场景。

缺点

  • 关闭标签页或浏览器窗口后,sessionStorage 会被清空,无法保存状态。

兼容性

sessionStorage 是广泛支持的 API,适用于以下浏览器:

3. 使用 performance.navigation API

浏览器的 performance.navigation API 提供了页面加载的详细信息,包括是否是通过刷新操作加载的页面。通过检查 performance.navigation.type 属性可以判断页面的加载方式。

window.onload = function() {
  if (performance.navigation.type === performance.navigation.TYPE_RELOAD) {
    console.log('页面被刷新');
  } else {
    console.log('首次加载页面');
  }
};

属性解释

  • performance.navigation.TYPE_RELOAD: 表示页面通过刷新加载。
  • 其他类型(如 TYPE_NAVIGATE)表示正常导航。

优点

  • 直接提供了判断页面刷新与否的接口,较为精确。
  • 不需要手动存储状态。

缺点

  • 该 API 正在逐步弃用,未来的浏览器可能不会支持。
  • 不适合未来长期维护的项目,应考虑迁移到更新的 API,比如下文中的 performance.getEntriesByType

兼容性

performance.navigation API 在大多数浏览器中都被支持,但该 API 已逐步被弃用:

4. 使用 beforeunload 事件

beforeunload 事件在用户离开页面之前触发,无论是页面刷新、关闭还是导航到其他页面。在此事件中,我们可以设置一个标志位来判断用户是否通过刷新离开当前页面。

window.addEventListener('beforeunload', function() {
  localStorage.setItem('isRefreshed', 'true');
});

window.onload = function() {
  if (localStorage.getItem('isRefreshed') === 'true') {
    console.log('页面被刷新');
    localStorage.removeItem('isRefreshed');  // 刷新后清除标志位
  } else {
    console.log('首次加载页面');
  }
};

工作原理

  • 在页面卸载时(包括刷新),通过 beforeunload 事件设置一个标志位。
  • 页面重新加载时,根据该标志位判断页面是否通过刷新操作加载。

优点

  • 灵活,可以处理不同类型的页面离开操作。
  • localStorage 的数据不会在页面关闭时清除,因此可以用于判断跨页面的刷新。

缺点

  • beforeunload 事件在部分浏览器(尤其是移动端)可能表现不一致。
  • 如果用户清除了浏览器缓存或 localStorage,则无法正确判断。

兼容性

beforeunload 事件在大多数现代浏览器中都有广泛支持,但可能在一些移动端浏览器上表现不一致:

5. 使用 performance.getEntriesByType

performance.getEntriesByType("navigation") 是一个现代 Web 性能 API,用于获取页面导航的详细信息。通过这个方法,我们可以获取一个包含导航信息的对象,并通过检查该对象的 type 属性,判断页面是通过刷新加载还是其他方式进入的。

示例代码

window.onload = function() {
  const [navigationEntry] = performance.getEntriesByType('navigation');
  
  if (navigationEntry && navigationEntry.type === 'reload') {
    console.log('页面被刷新');
  } else {
    console.log('首次加载页面');
  }
};

工作原理

  • performance.getEntriesByType('navigation') 返回一个 PerformanceNavigationTiming 对象数组,其中包含页面导航的详细信息。
  • 通过检查 navigationEntry.type,可以确定页面加载的类型:
    • type === 'reload': 页面通过刷新加载。
    • type === 'navigate': 页面通过正常导航进入。
    • type === 'back_forward': 页面通过浏览器的前进或后退按钮加载。
    • type === 'prerender': 页面通过预渲染加载(这个状态通常不常见)。

优点

  • 现代性performance.getEntriesByType 是较新的 API,能够在现代浏览器中准确区分页面的导航方式。
  • 详细信息:除了判断页面刷新,还可以获取更多关于页面加载性能的数据,如 DNS 解析时间、请求时间等,有助于调优页面性能。
  • 无状态管理:无需依赖 sessionStoragelocalStorage 等外部状态,避免了状态同步问题。

缺点

  • 浏览器兼容性:虽然大多数现代浏览器支持此 API,但 Internet Explorer 不支持(现在已不是问题)。
  • 不适用于多次刷新:如果需要在用户进行多次刷新的情况下进行追踪,单次判断可能不足。

使用场景

performance.getEntriesByType 适合那些只需要快速判断页面是否是刷新加载的场景,并且同时有进一步性能优化需求的应用。对于现代 Web 开发,这是一个较为精确且无需额外存储或会话管理的解决方案。

监控页面加载性能示例

window.onload = function() {
  const [navigationEntry] = performance.getEntriesByType('navigation');

  if (navigationEntry) {
    console.log(`页面加载类型: ${navigationEntry.type}`);
    console.log(`页面加载时间: ${navigationEntry.loadEventEnd - navigationEntry.startTime} ms`);
  }
};

这种方式不仅能帮助判断页面加载类型,还能帮助开发者优化页面性能,提供更多性能数据来分析页面加载瓶颈。

兼容性

performance.getEntriesByType 是较新的 API,在现代浏览器中得到广泛支持,但较旧浏览器不支持:

总结

判断页面是否刷新是一个常见的需求,本文介绍了五种技术方案。每种方案都有其特定的适用场景和优缺点。总结如下:

方案优点缺点浏览器兼容性
window.name简单、易跨页面保持状态安全性问题,需手动清理适用于所有现代浏览器
sessionStorage简单,不依赖复杂逻辑关闭标签页时清空支持现代浏览器及部分较旧浏览器
performance.navigation直接提供页面刷新判断API 正被弃用广泛支持,但逐渐被废弃
performance.getEntriesByType精确判断加载类型较新,旧版浏览器不支持仅支持现代浏览器
beforeunload灵活,可处理多种离开页面的操作部分浏览器不支持,尤其是在移动端大多数现代浏览器支持

不同的方案各有优劣,开发者应根据应用的目标用户群体、性能需求和浏览器支持情况灵活选择。如果需要简单、跨页面的刷新判断,window.name 是一个不错的选择;而在需要更精确、现代化的判断方式时,performance.getEntriesByType 提供了更高的灵活性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2126713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

超详细,手把手带你源码启动 Thingsboard-Gateway + MQTT 接入设备

超详细,手把手带你源码启动 Thingsboard-Gateway MQTT 接入设备 前置条件 thingsboard,我这里选择的是本地源码启动postgresql,这里采用的是个人服务器部署的公共服务EMQX,这里同样采用服务器部署的公共服务MQTTX 客户端Mysql【…

Fiddle的使用------一个非常好用且正规的抓包工具

Fiddle的下载安装(看完再去下载安装) https://www.telerik.com/download/fiddler 1.点击连接,在表格填上数据,点击下载,下载结束了就安装,一路next就可以了。 2.修改一下设置 以上跟我一样设置&#xff…

Unity 是否能和黑神话悟空一样,接入Nivida的DLSS,用NSight Graphics实际测试

NSight作为Nivida 显卡的调试工具,因为国内都是手游开发盛行的年代,远没有RenderDoc或者高通的QuatXXX 出名 选择NSight的原因很简单: Nividia 财大气粗,倒不是主因, 因为其CEO爱出名,所以手下的人只…

视觉SLAM ch5——相机与图像

一、单目模型 前言:本大标题下1~4部分讲述的都是单目针孔相机 SLAM的数学本质可以抽象为运动方程(x)和观测方程(z)(书上的第二部分) 教材第二章截图 书中P24页截图 其中的未知量为xk&#xff…

828华为云征文|几分钟,即可在华为云Flexus X服务器部署安全稳定的——水果生鲜商城配送小程序

最近由于公司需要开发一个水果生鲜同城配送的小程序,源码代码已经有了,相对于应的功能也开发的七七八八了,随着生鲜商城小程序的相对于应的功能开发逐渐接近尾声。 然而,在这个关键时刻,一个至关重要的决定摆在了团队面…

javase复习day22泛型、set、数据结构

泛型 package MyGenerics;import java.util.ArrayList; import java.util.Iterator;public class GenericsTest1 {public static void main(String[] args) {//没有泛型的情况ArrayList list new ArrayList();//所有数据都被认为是Object类型,都可以加入集合中list…

【操作系统】汇总二、进程管理

进程管理 二、进程与线程 文章目录 进程管理二、进程与线程1.程序1.1顺序执行的特征1.2并发执行的特征1.3 C语言编写的程序 2.进程Process2.1定义(组织)2.1.1程序段2.1.2数据段❗2.1.3进程控制块PCB1)内容2)作用3)进程…

C++详解string(全面解析)

目录 string的概念: string的框架: 1、成员函数 2、迭代器(Iterators)​编辑 3、容量 4、元素访问 5、修改 6、非成员函数重载 string的构造和拷贝构造: string的析构: string的访问:…

树模式数据表设计学习

引子: 场景:某读书网站,支持读者评论文章,并且对评论支持回复功能。设计的表如下: 问题点:你想获取一个评论下所有的评论信息? 将所有评论一次性取出、轮巡遍历,获取到所有数据。 …

几款可以让销售管理事倍功半的CRM软件推荐!

本文将盘点几款CRM软件,为企业选型提供参考! 想象一下这样一个场景,一家企业的销售团队每天忙碌地跟进客户,却因为信息分散、管理混乱而效率低下。CRM 软件就如同一位得力助手,将客户信息有序整合,助力企业…

Unity核心实践小项目

要源码包的私信我。 简介 衔接Unity核心学习后的实操小项目 需求分析 准备工作 面板基类 为了能够控制一画布整体的透明度,所以需要给每个面板都添加一个 CanvasGroup组件 UI管理器 UGUI方面的参数设置 开始场景 场景搭建 直接用资源包搭建好的场景:…

VD1013 DFN小封装芯片 适用于小电流的输出的电池保护芯片

VD1013内置高精度电压检测电路和延迟电路以及内置MOSFET,是用于单节锂离子/锂聚合物可再充电电池的保护IC。 本IC适合于对1节锂离子/锂聚合物可再充电电池的过充电、过放电和过电流进行保护 。 VD1013具备如下特点: 高精度电压检测电路 过充电检测电压…

chfsgui局域网共享局域网http服务 Cute HTTp File Server软件

Cute HTTp File Server https://wwaz.lanzouv.com/iGHIj29srj0b 密码:eaq3

OpenHarmony鸿蒙( Beta5.0)智能窗户通风设备开发详解

鸿蒙开发往期必看: 一分钟了解”纯血版!鸿蒙HarmonyOS Next应用开发! “非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零基础入门到精通) “一杯冰美式的时间” 了解鸿蒙HarmonyOS Next应用开发路…

区块链积分系统:革新支付安全与用户体验的未来

在数字时代,确保交易过程中的安全性和风险控制变得至关重要。随着传统支付系统在处理大规模交易时面临的挑战,如繁琐的审核、严格的监管以及欺诈风险,这些问题不仅影响了交易效率,还可能给用户和企业带来经济损失。因此&#xff0…

【CanMV K230 AI视觉】 跌倒检测

【CanMV K230 AI视觉】 跌倒检测 跌倒检测 动态测试效果可以去下面网站自己看。 B站视频链接:已做成合集 抖音链接:已做成合集 跌倒检测 跌倒检测主要根据人体姿态来判断,可以用于老人、小孩跌倒监护。 实验名称:跌倒检测 实验…

基于单片机的电子药箱控制系统设计

本设计采用STM32F103C8T6单片机作为电子药箱的主控单元,组成模块包括时钟芯片DS1302、语音提醒模块WT588D、液晶显示模块LCD1602、红外避障传感器FC-51、电磁锁驱动电路和通信模块SIM800C。系统初始化结束,红外传感器检测药物的剩余情况并将信息上传到主…

虚拟机器配置固定IP地址

新安装的虚拟机,如何配置固定的ip地址,废话少说直接上干货 第一步:在VMarea中 选中你要固定IP的虚拟机器,点击上面的“编辑”按钮,然后找到“虚拟网络编辑器”,选中你要修改的ip VMnet8,然后是…

力扣题解2555

大家好,欢迎来到无限大的频道。 今日继续给大家带来力扣题解。 题目描述: 两个线段获得的最多奖品 在 X轴 上有一些奖品。给你一个整数数组 prizePositions ,它按照 非递减 顺序排列,其中 prizePositions[i] 是第 i 件奖品的位…

01 Docker概念和部署

目录 1.1 Docker 概述 1.1.1 Docker 的优势 1.1.2 镜像 1.1.3 容器 1.1.4 仓库 1.2 安装 Docker 1.2.1 配置和安装依赖环境 1.3镜像操作 1.3.1 搜索镜像 1.3.2 获取镜像 1.3.3 查看镜像 1.3.4 给镜像重命名 1.3.5 存储,载入镜像和删除镜像 1.4 Doecker…