You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用户离开页面前执行代码失效?React/Next.js下的正确实现方式

在React/Next.js中实现页面离开时执行代码的正确方案

你之前尝试的alert无效是因为现代浏览器对beforeunload/unload事件中的同步弹窗做了严格限制,目的是防止恶意网站滥用这类弹窗干扰用户。以下是针对React和Next.js的可行实现方案:

一、触发离开确认提示(提醒用户不要离开)

如果你的需求是在用户离开时弹出浏览器默认的确认对话框,可通过beforeunload事件实现:

'use client'; // Next.js App Router 需添加此指令,Pages Router 无需
import { useEffect } from 'react';

export default function YourPage() {
  useEffect(() => {
    const handleBeforeUnload = (e) => {
      // 必须返回一个非空字符串,浏览器会用此触发确认提示(部分浏览器会忽略自定义文本)
      e.preventDefault();
      e.returnValue = '';
      return '';
    };

    window.addEventListener('beforeunload', handleBeforeUnload);
    return () => {
      window.removeEventListener('beforeunload', handleBeforeUnload);
    };
  }, []);

  return <div>你的页面内容</div>;
}

注意:自定义提示文本在Chrome、Firefox等主流浏览器中已被屏蔽,最终显示的是浏览器默认文案。

二、执行无UI的后台逻辑(如上报、数据保存)

如果需要在用户离开时执行上报数据、保存状态等无UI操作,不要用alert这类同步弹窗,推荐使用以下可靠方案:

1. 使用navigator.sendBeacon(推荐)

这是浏览器专门为页面卸载时发送数据设计的API,异步且浏览器会保证请求完成:

'use client';
import { useEffect } from 'react';

export default function YourPage() {
  useEffect(() => {
    const handleUnload = () => {
      // 发送数据到后端,支持FormData、Blob或字符串
      const data = new FormData();
      data.append('action', 'user_left');
      data.append('page', window.location.pathname);
      
      navigator.sendBeacon('/api/user-behavior', data);
    };

    window.addEventListener('unload', handleUnload);
    return () => {
      window.removeEventListener('unload', handleUnload);
    };
  }, []);

  return <div>你的页面内容</div>;
}

2. 使用fetch的keepalive选项

如果需要更灵活的请求配置,可给fetch添加keepalive: true:

'use client';
import { useEffect } from 'react';

export default function YourPage() {
  useEffect(() => {
    const handleUnload = async () => {
      await fetch('/api/user-behavior', {
        method: 'POST',
        body: JSON.stringify({ action: 'user_left', page: window.location.pathname }),
        headers: { 'Content-Type': 'application/json' },
        keepalive: true, // 关键配置,保证请求在页面卸载时完成
      });
    };

    window.addEventListener('unload', handleUnload);
    return () => {
      window.removeEventListener('unload', handleUnload);
    };
  }, []);

  return <div>你的页面内容</div>;
}

关键注意事项

  • 不要在beforeunload/unload事件中执行耗时的同步或异步操作,浏览器可能会直接中断。
  • unload事件的执行时机较晚,优先用beforeunload配合sendBeacon(部分场景下beforeunload触发时也可调用sendBeacon)。
  • Next.js的App Router中,所有使用浏览器API的组件必须添加'use client'指令,否则会在服务端渲染时报错。

内容的提问来源于stack exchange,提问作者Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 20:51:06