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

Next.js如何在用户离开页面时触发自定义函数?

问题原因

浏览器出于安全策略限制,禁止在beforeunload事件回调中调用alert、confirm、prompt等弹窗类API,你遇到的拦截报错是浏览器的强制行为,没有绕过方案。

完整实现方案

你需要分开处理浏览器级别的页面离开和Next.js内部路由跳转离开两种场景,你的代码里之前忽略的routeChangeStart事件正是用来处理内部路由跳转的核心逻辑:

1. 工具逻辑(适配你的catch-all路由)

直接用Next.js内置的useRouter拿聊天室ID,不用单独封装getChatRoomId:

import { useRouter } from 'next/router'
import { useEffect } from 'react'
import Router from 'next/router'

// 组件内获取路由参数
const router = useRouter()
// [...messages]的第一个参数就是聊天室ID或者'new'
const chatRoomId = router.query.messages?.[0]

2. 完整监听逻辑

useEffect(() => {
  if (!chatRoomId) return

  console.log('----HAS ENTERED /messages/* ------', chatRoomId)

  // 处理浏览器级别的离开:关闭页面、刷新页面、跳转到外部站点
  const beforeunload = (e) => {
    // 不需要用户交互的逻辑直接执行:比如日志上报、状态同步
    console.log(`---- IS LEAVING /messages/${chatRoomId} ------`)
    // 异步上报请求优先用navigator.sendBeacon,不会被浏览器拦截
    // navigator.sendBeacon('/api/chat/leave', JSON.stringify({ id: chatRoomId }))

    // 若需要弹确认框提示用户,用标准写法,浏览器会弹自带的确认弹窗
    e.preventDefault()
    e.returnValue = '确定要离开聊天室吗?未保存的内容将会丢失'
    return e.returnValue
  }

  // 处理Next.js内部路由跳转的离开:点击站内链接跳转到其他页面
  const routeChangeStart = (targetUrl) => {
    // 这里不受beforeunload限制,可以执行任意自定义逻辑:弹自定义弹窗、调用接口等
    console.log(`---- 正在跳转到站内页面 ${targetUrl},离开聊天室 ${chatRoomId} ------`)

    // 若需要拦截跳转做用户确认,可以用以下逻辑终止跳转,用户确认后再手动调用Router.push(targetUrl)
    // Router.events.emit('routeChangeError')
    // throw new Error('路由跳转已终止')
  }

  window.addEventListener('beforeunload', beforeunload)
  Router.events.on('routeChangeStart', routeChangeStart)

  return () => {
    window.removeEventListener('beforeunload', beforeunload)
    Router.events.off('routeChangeStart', routeChangeStart)
  }
}, [chatRoomId])

注意事项

  • 新浏览器中beforeunload返回的自定义提示文案不会生效,只会显示浏览器默认的确认提示,属于正常现象
  • 若不需要拦截用户离开行为,只是要触发执行指定逻辑,去掉beforeunload里的e.preventDefault和return相关代码即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 21:18:02