当前位置: 首页 > 知识库问答 >
问题:

前端 - vue3 监听浏览器窗口关闭事件,该如何实现在窗口close前发送请求记录日志,并确保后台请求一定能执行完成?

谢锦程
2024-02-04

vue3 监听浏览器窗口关闭事件,在窗口close前发送一个请求记录下使用记录这样子。
但是实际使用过程中发现有时候调请求存记录会不成功,并不是每次在使用完关闭窗口后都成功的存了使用记录。
请问是由于请求完成前浏览器已经关闭了导致请求取消造成的嘛?如果是的话,该如何确保在窗口关闭前,发送后台请求,且确保能请求执行完成呢?

代码如下:

//监听 浏览器窗口关闭事件,触发日志上传onMounted(() => {    window.addEventListener("beforeunload", (e) => beforeunloadHandler(e));    window.addEventListener("unload", (e) => unloadHandler(e));});onUnmounted(() => {    window.removeEventListener("beforeunload", (e) => beforeunloadHandler(e));    window.addEventListener("unload", (e) => unloadHandler(e));});const beforeunloadHandler = async (event: any) => {    if (state.totalPressCount > 0) {        logEndTime.value = dayjs().format('YYYY-MM-DD HH:mm:ss');//add2023-07-25 plq        // await submitAlarmCaseToolLog();    }    //网页上 显示确认对话框    // Cancel the event as stated by the standard.    // event.preventDefault(); // 取消默认的关闭操作    // Chrome requires returnValue to be set.    // event.returnValue = ""; // Chrome要求设置返回值才能触发提示框}const unloadHandler = async (event: any) => {    if (state.totalPressCount > 0) {        // logEndTime.value = dayjs().format('YYYY-MM-DD HH:mm:ss');//add2023-07-25 plq        await submitAlarmCaseToolLog();    }}//添加事件工具使用记录 add2023-07-25 plqconst submitAlarmCaseToolLog = async () => {    const _requestData = {        alarmCaseId: alarmCase_store.alarmCaseData?.id as number,        toolKitId: guidanceToolsIdEnum.cpr_guide_tool,        openTime: logStartTime.value,        closeTime: logEndTime.value,        resultId: "",        resultName: `累计按压计数:${state.totalPressCount}`,        assessFlowId: paramAssessFlowId.value,//问题关联工具 add2023-07-27 plq        orderId: paramAssessOrderId.value,        guidanceStepId: paramStepId.value, //指导步骤关联工具        guidanceStepSourceId: paramStepSourceId.value,    };    let _res = (await addAlarmCaseToolLog(_requestData)).data;    // console.log(_res);};

共有4个答案

扶冠宇
2024-02-04
  window.addEventListener('beforeunload', () => {    let blob = new Blob([JSON.stringify(params)], {      type: 'application/json',    });    navigator.sendBeacon(window.location.origin+'请求路径',blob);  })  window.addEventListener("unload", () => { //部分手机可以获取到     let blob = new Blob([JSON.stringify(params)], {      type: 'application/json',    });    navigator.sendBeacon(window.location.origin+'请求路径',blob);  })  window.addEventListener("pagehide", () => {    clearInterval(timer)    let blob = new Blob([JSON.stringify(params)], {      type: 'application/json',    });    localStorage.setItem('pagehide','pagehide')    navigator.sendBeacon(window.location.origin+'请求路径',blob);  },false);  document.addEventListener("visibilitychange", () => {    clearInterval(timer)    let blob = new Blob([JSON.stringify(params)], {      type: 'application/json',    });    localStorage.setItem('visibilitychange','visibilitychange')    navigator.sendBeacon(window.location.origin+'请求路径',blob);  })  window.addEventListener("visibilitychange", () => {    let blob = new Blob([JSON.stringify(params)], {      type: 'application/json',    });    localStorage.setItem('winvisibilitychange','visibilitychange')    navigator.sendBeacon(window.location.origin+'请求路径',blob);  })
邵繁
2024-02-04

这种场景浏览器有提供专门的API sendBeacon
https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/se...
image.png

经兴安
2024-02-04

https://developer.mozilla.org/zh-CN/docs/Web/API/Beacon_API

许安邦
2024-02-04

从你的代码中看,你已经在窗口关闭事件中添加了请求记录日志的操作,但你遇到的问题是请求并不总是能成功执行。这是因为浏览器的安全策略不允许在窗口或标签页即将关闭时执行某些网络请求。

对于这种情况,一种可能的解决方案是使用fetch API 或 axios 这样的库来发送请求,并在请求的 promise 中使用 catch 来处理可能出现的错误。这样,即使请求因为浏览器的原因被取消,你也能捕获到错误并处理。

下面是一个使用 axios 的例子:

const submitAlarmCaseToolLog = async () => {    try {        const _requestData = {            alarmCaseId: alarmCase_store.alarmCaseData?.id as number,            toolKitId: guidanceToolsIdEnum.cpr_guide_tool,            openTime: logStartTime.value,            closeTime: logEndTime.value,            resultId: "",            resultName: `累计按压计数:${state.totalPressCount}`,            assessFlowId: paramAssessFlowId.value,//问题关联工具 add2023-07-27 plq            orderId: paramAssessOrderId.value,            guidanceStepId: paramStepId.value, //指导步骤关联工具            guidanceStepSourceId: paramStepSourceId.value,        };        let _res = (await axios.post('/your-api-endpoint', _requestData)).data;        // console.log(_res);    } catch (error) {        console.error('Failed to submit log:', error);    }};

这样,如果请求因为浏览器的原因被取消,catch 块将会捕获到错误,并打印出错误信息。你可以根据需要进一步处理这个错误,例如重新发送请求或者给用户显示一个错误消息。

 类似资料:
  • vue3 监听浏览器窗口关闭事件,在窗口close前发送一个请求? 现在想在浏览器窗口关闭前给后台发个请求,但是在window的beforeunload里写好像不触发?请问该如何解决呢?

  • 问题内容: 我试图找出用户何时离开指定页面。找出他何时使用页面内的链接进行导航是没有问题的,但是我有点需要标记一些东西,例如当他关闭窗口或键入另一个URL并按Enter时。第二个不是那么重要,但第一个是重要。所以这是一个问题: 我如何查看用户何时关闭我的页面(捕获window.close事件),然后……并没有什么关系(我需要发送AJAX请求,但是如果可以获取它以运行警报,我可以剩下的)。 问题答案

  • 监听微信H5页面关闭,需要在此时机发送请求添加历史记录,我在onHide,onUnload事件中发送请求安卓手机没问题,但是苹果手机却无法监听到。 在网上找了很多方法如:window.addEventListener('pagehide'() => {})和window.addEventListener('visibilitychange'() => {}) 甚至使用navigator.sendB

  • 问题内容: 我想捕获浏览器窗口/选项卡关闭事件。我已经尝试使用jQuery以下内容: 但这也适用于表单提交,这不是我想要的。我想要一个仅在用户关闭窗口时才触发的事件。 问题答案: 每当用户出于任何原因离开您的页面时,都会触发该事件。 例如,如果用户提交表单,单击链接,关闭窗口(或选项卡)或使用地址栏,搜索框或书签进入新页面,则将触发该事件。 您可以使用以下代码排除表单提交和超链接(其他框架除外):

  • 问题内容: 我尝试使用以下代码在关闭浏览器窗口时收到警报: 它可以工作,但是如果页面包含一个超链接,则单击该超链接会引发相同的警报。仅在关闭浏览器窗口时才需要显示警报,而在单击超链接时则不需要。 问题答案: 保持您的代码不变,并使用jQuery处理链接:

  • 上一步中我们已经定义好了Server接口,并进行了多次重构,但是实际上那个Server是没啥毛用的东西。现在要为其添加真正有用的功能。大师说了,饭要一口一口吃,衣服要一件一件脱,那么首先来定个小目标——启动ServerSocket监听请求,不要什么多线程不要什么NIO,先完成最简单的功能。下面还是一步一步来写代码并进行重构优化代码结构。 关于Socket和ServerSocket怎么用,网上很多文