Nuxt框架Vue页面调用重启API后alert弹窗OK按钮偶发失效问题咨询
问题根本原因
你遇到的弹窗点击无响应问题和Chrome、Vue、Nuxt框架无关,是两个问题共同作用的结果:
- 错误的alert传参写法导致浏览器主线程阻塞:你在catch块中写的
alert('Agent has a error to restart >>', err)不符合alert的语法规范,alert仅支持接收一个参数,当你传入第二个err对象时,浏览器会尝试对错误对象做序列化处理,如果错误对象包含循环引用、内容体积较大,序列化过程会完全占用浏览器主线程,导致弹窗交互无响应,刚好你后端接口设置的超时时间是3000ms,等超时流程跑完、序列化完成后,交互就恢复正常了。 - 后端调用的重启接口大概率是同步阻塞类型:你后端调用的
http://agentUrl/v1/restart接口如果是等到应用真正重启完成才返回响应,就会出现请求长时间挂起的情况,请求pending过程中如果有其他浏览器任务抢占主线程,也会间接导致弹窗交互异常。
修复方案
- 修正alert的参数写法,先把错误内容转成字符串再传入:
// 把catch块的代码改成下面的写法 .catch((err)=>{ const errMsg = err.message || JSON.stringify(err) alert(`Agent has a error to restart >> ${errMsg}`) })
- 给按钮添加点击事件绑定(你当前的模板代码里没加
@click="restart",如果是复制漏了可以忽略),同时加loading状态,点击后禁用按钮避免重复发起请求:
<template> <button @click="restart" :disabled="loading"> {{ loading ? '重启中' : 'restart' }} </button> </template> <script> import { createRestart } from '@/api/agent' export default { data() { return { loading: false } }, methods:{ async restart() { if (confirm('Restart agent?')) { this.loading = true try { const res = await createRestart() if (res.status == 200) { alert('Agent is restarted') }else{ alert("Agent isn't restarted") } } catch(err) { const errMsg = err.message || JSON.stringify(err) alert(`Agent has a error to restart >> ${errMsg}`) } finally { this.loading = false } } }, } } </script>
- 调整后端重启接口逻辑:如果agent的重启接口是同步阻塞的,可以改成先返回200响应,再后台执行重启操作,避免请求超时。
- 有条件的话可以替换原生alert为项目UI组件库的模态框组件,原生alert是浏览器级别的同步阻塞弹窗,只要主线程有未执行完的任务就会出现交互失效问题,自定义DOM模态框不会有这个限制。
内容的提问来源于stack exchange,提问作者niddddddfier
相关产品推荐
相关产品推荐

