V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
aizya
V2EX  ›  JavaScript

js 怎么判断用户关闭了浏览器

  •  
  •   aizya · 2021-09-15 09:19:54 +08:00 · 10279 次点击
    这是一个创建于 925 天前的主题,其中的信息可能已经有所发展或是发生改变。

    各位大哥,请问一下使用 js 怎么判断用户关闭了浏览器, 我现在用的是 window.onbeforeunload,但是没办法区分 tab 页面关闭、刷新和浏览器关闭。 求教。

    64 条回复    2021-09-16 18:22:34 +08:00
    horizon
        1
    horizon  
       2021-09-15 09:22:23 +08:00
    没办法
    kop1989
        2
    kop1989  
       2021-09-15 09:28:41 +08:00
    不太理解区分页签关闭和浏览器 app 关闭的业务场景。
    一个页签,就是一个浏览器进程。
    v2byy
        3
    v2byy  
       2021-09-15 09:30:04 +08:00 via iPhone
    js run 在 render 进程里面的,感知不了 browser 进程吧
    yunyuyuan
        4
    yunyuyuan  
       2021-09-15 09:32:55 +08:00   ❤️ 3
    这个涉及了用户隐私吧。https://stackoverflow.com/questions/3888902/detect-browser-or-tab-closing

    你可以用 sessionStorage,这个数据只持续到浏览器关闭
    dzdh
        5
    dzdh  
       2021-09-15 09:37:16 +08:00   ❤️ 2
    ws 断开就关了
    IceBay
        6
    IceBay  
       2021-09-15 09:37:35 +08:00
    每隔一段时间更新时间戳到 localStorage 进行对比?
    MoeMoesakura
        7
    MoeMoesakura  
       2021-09-15 09:41:16 +08:00
    @dzdh 不能保证吧,要是用户合上了笔记本,进入睡眠模式,你怎么判断啊
    FaiChou
        8
    FaiChou  
       2021-09-15 09:44:42 +08:00
    还是说清楚下具体需求吧, 不然光从你的问题来看, 用户关闭了浏览器(tab), 进程(线程)都杀死了, js 肯定都被干掉了, 你的判断逻辑也不能正常运行.
    aristolochic
        9
    aristolochic  
       2021-09-15 09:46:30 +08:00   ❤️ 1
    瞧这问题问的,要是用户用一个软件的 WebView 打开你的网站,你难道还想去监听这个用户是关了你的页面还是关了整个软件? Web 怎么可能让你知道那么多,岂不是反了天了。现在浏览器标准都是安全越收越紧,是绝对不可能再出一个 API 告诉你浏览器关了的。

    说白了对于 Web 而言,网站是不应该也不可能 Native aware 的,且不说 Tab 这些概念不是所有浏览器都有,比如有那种就一个页面的浏览器( surf 就是,在平铺窗口管理器生态有一定市场),还有那么多 WebView 也是没有标签的,更不可能让你了解到原生的情况。

    浏览器插件 /扩展倒是可以知道标签的状态,具体能不能知道浏览器关没关就没了解过了。

    要想完全控制,老老实实套 Electron 。
    itechnology
        10
    itechnology  
       2021-09-15 09:51:47 +08:00
    我觉得是做不到的。浏览器不可能让你知道它是否被关闭了。
    Rheinmetal
        11
    Rheinmetal  
       2021-09-15 09:55:13 +08:00   ❤️ 30
    今天想知道关闭浏览器
    明天想干什么我都不敢想了
    :doge:
    fregie
        12
    fregie  
       2021-09-15 10:18:17 +08:00
    runtime 都没了,你的代码都运行不了了,要怎么判断..
    dzdh
        13
    dzdh  
       2021-09-15 10:18:32 +08:00
    @MoeMoesakura 跟关了 tab 有啥区别
    mywaiting
        14
    mywaiting  
       2021-09-15 10:23:02 +08:00
    想知道浏览器是否关闭,如果条件合适还是可以做到的

    举个例子来说,稍有点互联网经验的同学都会装 ADBlock 插件,页面引入的 JS 检测一下 ADBlock 插件的 API 能否调用就能检测浏览器是否在关闭状态

    不过这里面有个鸡先还是蛋先的问题,浏览器都关闭,还怎么页面引入 JS 来检测?

    很尴尬对吧?
    sampeng
        15
    sampeng  
       2021-09-15 10:29:03 +08:00
    你是想浏览器关闭,弹出来:“你真的想关吗?不要关好吗”
    cyrbuzz
        16
    cyrbuzz  
       2021-09-15 10:37:00 +08:00
    道是有的,不过比较奇怪,要看用户是否接受。

    昨天撸了一遍 Chrome 插件编写,其中有 tabs 权限与 window 权限(这个随便自己配)的插件,可以通过 tabs 的 onRemoved 和 window 的 onRemoved 事件监听到标签以及整个窗口的关闭,这样就可以感知到时 tab 的关闭还是窗口的关闭。

    所以这个道可以是引导用户安装你的特定插件。

    tabs remove https://developer.chrome.com/docs/extensions/reference/tabs/#method-remove

    window remove https://developer.chrome.com/docs/extensions/reference/windows/

    另外这种需求也比较好奇...
    TomatoYuyuko
        17
    TomatoYuyuko  
       2021-09-15 10:45:07 +08:00
    如果你想做清除操作,一般是在进入页面初始化的时候做,而不是离开页面的时候做。类似的操作大多如此。
    fkdtz
        18
    fkdtz  
       2021-09-15 10:54:08 +08:00   ❤️ 7
    就像黄志诚和韩琛怎么知道陈永仁和刘建明有没有被发现甚至挂了?定期联系联系呗。

    要是哪天联系不上了,八成是挂了。
    dunn
        19
    dunn  
       2021-09-15 10:56:50 +08:00 via iPhone
    @sampeng 请选择 再看一会 残忍关闭
    lin07hui
        20
    lin07hui  
       2021-09-15 11:02:12 +08:00
    tab 页面关闭和浏览器关闭 这也要区别?
    刷新可以使用 sessionStorage 来做
    Yvette
        21
    Yvette  
       2021-09-15 11:07:48 +08:00
    dfkjgklfdjg
        22
    dfkjgklfdjg  
       2021-09-15 11:24:16 +08:00
    单纯区分浏览器刷新和关闭页面就好了,关注是否关注了浏览器是什么鬼,和你没关系啊。
    statement
        23
    statement  
       2021-09-15 11:26:47 +08:00
    遇到过相同需求 B 端产品可以解决 用 app 模式就行 C 端监测心跳不准确
    wolfan
        24
    wolfan  
       2021-09-15 11:27:45 +08:00
    不如断定是否重新打开了浏览器。
    而且像 edge 内置了休眠,长时间不活动页面会被主动休眠的。
    yousabuk
        25
    yousabuk  
       2021-09-15 11:29:36 +08:00 via iPhone
    你得像网银控件那么干
    hanssx
        26
    hanssx  
       2021-09-15 11:32:44 +08:00
    websocket 心跳
    shyling
        27
    shyling  
       2021-09-15 11:56:46 +08:00
    每个页面连个 ws 。。全断了就当关浏览器了
    GeruzoniAnsasu
        28
    GeruzoniAnsasu  
       2021-09-15 12:04:04 +08:00
    大胆一点,快进到产品包一个有后门的浏览器
    TomChaai
        29
    TomChaai  
       2021-09-15 12:24:35 +08:00
    这个问题等效于“电脑怎么知道用户拔了电源”。
    要么时刻后台刷新,长时间断开视作关闭,要么非正常 exit,下次再上线的时候处理
    sha851092391
        30
    sha851092391  
       2021-09-15 12:36:58 +08:00
    这个需求很简单吧,在 window.onbeforeunload 弹出对话框,询问用户 “请选择你关闭的原因:1 、标签页关闭; 2 、刷新; 3 、浏览器关闭; 4 、不告诉你”,这样实现还合法,完美~
    SixGod66
        31
    SixGod66  
       2021-09-15 12:42:06 +08:00
    js 设置没有过期时间的 cookie,在浏览器关闭时会自动清空。sessionStorage 在最新的 Chrome 中已经无法跨标签共享数据了
    meiyoumingzi6
        32
    meiyoumingzi6  
       2021-09-15 13:25:12 +08:00
    js 怎么感知电脑关闭了? 手动狗头
    2i2Re2PLMaDnghL
        33
    2i2Re2PLMaDnghL  
       2021-09-15 13:25:40 +08:00
    信不信我把宇宙停了三十年再给你继续?没错,正好当你看到这句话的时候。
    你怎么检测到宇宙停了?
    外部可以内视,但内部不可外视
    kisshere
        34
    kisshere  
       2021-09-15 14:39:32 +08:00 via Android
    ws,或者 Ajax 心跳,后端参与才行
    Justin13
        35
    Justin13  
       2021-09-15 14:50:41 +08:00 via Android
    这要能区分出来,那不就是 bug 了么
    afirefish
        36
    afirefish  
       2021-09-15 15:03:21 +08:00
    ws+心跳,断开了就是关闭了
    qwerthhusn
        37
    qwerthhusn  
       2021-09-15 15:20:44 +08:00   ❤️ 2
    死刑犯怎么判断自己还有没有被枪毙
    WordlessEcho
        38
    WordlessEcho  
       2021-09-15 15:24:40 +08:00
    我在前端写了一个删除撤销的功能(就是延迟几秒再删除),但是页面关闭了之后删除请求就发不出去了(
    zhw2590582
        39
    zhw2590582  
       2021-09-15 15:25:28 +08:00
    我怎么判断我睡着了
    ws52001
        40
    ws52001  
       2021-09-15 15:59:53 +08:00
    这个要求有点过分的。。
    robinlovemaggie
        41
    robinlovemaggie  
       2021-09-15 16:14:09 +08:00
    你这我问题让我想起前两天有人问:人怎么知道死后有没有灵魂?
    lakehylia
        42
    lakehylia  
       2021-09-15 16:23:00 +08:00
    楚门怎么知道自己生活在虚拟的世界里?他自己是不知道的,只有世界之外的女主进来了,他才知道。
    codehz
        43
    codehz  
       2021-09-15 16:29:03 +08:00 via Android
    刷新还是可以做的
    用 PerformanceNavigationTiming.type 判断即可
    shellus
        44
    shellus  
       2021-09-15 17:26:12 +08:00
    @zhw2590582 明天醒来你就知道了
    StephenHe
        45
    StephenHe  
       2021-09-15 17:49:36 +08:00
    又要强奸用户
    cw2k13as
        46
    cw2k13as  
       2021-09-15 17:56:24 +08:00
    websocket
    hengshenyu
        47
    hengshenyu  
       2021-09-15 18:32:50 +08:00   ❤️ 1
    好像很多人觉得不行啊?我觉得理论上还是有可行性的
    1. 首先 onbeforeunload 这个接口在 tab 关闭时会触发
    2. Navigator.sendBeacon()这个接口在浏览器关闭和 tab 关闭都会触发,没错:虽然不能告诉死人他死了,但是可以告诉他家人(即使浏览器关了也可以通知后端)

    那么:在 1 没触发且 2 触发了,此时即为用户关闭了浏览器而不是关闭了标签页。

    以上仅理论
    o00o
        48
    o00o  
       2021-09-15 18:47:58 +08:00
    @meiyoumingzi6
    @2i2Re2PLMaDnghL
    @qwerthhusn
    @zhw2590582 人类怎么判断自己是真实活着还是只是大脑活着
    SenLief
        49
    SenLief  
       2021-09-15 18:55:46 +08:00
    不能被动判断,但是可以主动吧,比如填表单的时候如果关闭或者刷新就会弹窗,这是如何实现的?
    wangbenjun5
        50
    wangbenjun5  
       2021-09-15 20:17:47 +08:00
    思路奇异啊,怎么判断用户关闭浏览器?假设有方法判断用户关闭浏览器,然后呢?是要阻止用户关闭浏览器吗?哈哈,幸亏 chrome 没有提供这个 API,不然流氓网站上了天
    xuanbg
        51
    xuanbg  
       2021-09-15 20:22:28 +08:00
    这就好比你自怎么知道自己死掉了一样。答案就是没办法知道。因为你都没有意识了啊

    浏览器都关掉了,你一个运行在浏览器里面的 JS 代码,也就同时被关掉了,就算你知道了,也干不了啥事情。。。
    jeeyong
        52
    jeeyong  
       2021-09-15 20:34:59 +08:00
    以前我记得有个 window.close() 类似的事件?
    那会用来做关闭页面后, 弹出广告..
    yolee599
        53
    yolee599  
       2021-09-15 20:48:41 +08:00 via Android
    换一个说法,电脑怎么判断用户拔掉了主机电源?
    44670
        54
    44670  
       2021-09-15 20:57:51 +08:00
    navigator.sendBeacon
    试试这个
    ipwx
        55
    ipwx  
       2021-09-15 21:07:44 +08:00
    @WordlessEcho 你这思路有问题,应该是延迟几秒再确认删除。。。
    MrKrabs
        56
    MrKrabs  
       2021-09-15 22:28:51 +08:00   ❤️ 1
    人怎么判断自己死了
    2i2Re2PLMaDnghL
        57
    2i2Re2PLMaDnghL  
       2021-09-16 02:11:14 +08:00
    @hengshenyu 1. beforeunload 在浏览器关闭时也会触发
    2. sendBeacon 不是一个可供产生触发的接口,它是一个替代 XHR 和 fetch 的请求用接口。

    @jeeyong 因为历史原因,window 是指标签页

    @SenLief beforeunload 事件
    liuidetmks
        58
    liuidetmks  
       2021-09-16 06:34:55 +08:00 via iPhone
    我专门在火狐中 关闭了 beforeunload 事件,
    觉得弹出提示的网站好烦
    gogolang
        59
    gogolang  
       2021-09-16 08:54:58 +08:00
    js 定时发送 http 请求,什么时候请求停了就是关闭浏览器了。
    你看这样行不?
    luzemin
        60
    luzemin  
       2021-09-16 09:01:58 +08:00
    window.onbeforeunload 拦住弹个窗问用户,你是在关闭 Tab 还是关闭浏览器?(逃
    meepo3927
        61
    meepo3927  
       2021-09-16 10:04:50 +08:00
    tab 关闭和浏览器关闭, 区分不了。

    而且浏览器窗口也是可以多开的, 你需要拿到程序进程才能判断。
    systemcall
        62
    systemcall  
       2021-09-16 10:43:56 +08:00
    让用户换成 IE8 或者 IE6,之后用万能的 ActiveX,给用户装个驱动,你连用户关闭了哪个浏览器、关闭了浏览器之后再做什么都知道的一清二楚
    MoeMoesakura
        63
    MoeMoesakura  
       2021-09-16 18:14:46 +08:00
    @dzdh 那个例子不贴切,举个无聊的例子:用户用一个丢包率极高的网络(长宽),ws 你怎么确定一直在线(((
    dzdh
        64
    dzdh  
       2021-09-16 18:22:34 +08:00
    @MoeMoesakura 99%丢包的话那就认为这个用户不存在啊。难不成是付费聊天应用,按秒收费的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4999 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 01:14 · PVG 09:14 · LAX 18:14 · JFK 21:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.