Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我想在用户关闭浏览器选项卡时将数据发布到API_Javascript_Laravel_Vue.js_Vuejs2 - Fatal编程技术网

Javascript 我想在用户关闭浏览器选项卡时将数据发布到API

Javascript 我想在用户关闭浏览器选项卡时将数据发布到API,javascript,laravel,vue.js,vuejs2,Javascript,Laravel,Vue.js,Vuejs2,我被困在一个场景中,需要你们的帮助。 目前,我正在开发一个功能,可以锁定其他管理员的预订。 我在bookings表中创建了一个字段,当管理员进入该预订时,我将用户id放入其中,该字段将使用当前管理员id进行更新,而其他管理员此时确实可以访问该预订 因此,问题是,如果用户关闭了该选项卡,其他管理员的预订也会被锁定 我在vueJs中尝试了许多不同的方法,例如beforeunload方法。 我使用过Xhr方法,axios在这种情况下都失败了。 我还能做些什么来解决这个问题 removeUser ()

我被困在一个场景中,需要你们的帮助。 目前,我正在开发一个功能,可以锁定其他管理员的预订。 我在bookings表中创建了一个字段,当管理员进入该预订时,我将用户id放入其中,该字段将使用当前管理员id进行更新,而其他管理员此时确实可以访问该预订

因此,问题是,如果用户关闭了该选项卡,其他管理员的预订也会被锁定

我在vueJs中尝试了许多不同的方法,例如
beforeunload
方法。 我使用过Xhr方法,axios在这种情况下都失败了。 我还能做些什么来解决这个问题

removeUser () {

    var params = JSON.stringify({ locked_by: '' });
    let xhr = new XMLHttpRequest()
    xhr.open('PUT',Url, true)
    xhr.setRequestHeader("Authorization", 'Bearer ' + localStorage.getItem('app_access_token'))
    xhr.setRequestHeader("Content-length", params.length);
    xhr.setRequestHeader("Content-type", "application/json; charset=utf-8")
    xhr.responseType = 'arraybuffer'
    xhr.onreadystatechange = function() {//Call a function when the state changes.
    if(xhr.readyState == 4 && xhr.status == 200) {
        alert(xhr.responseText);
    }
}
xhr.send(params);
还尝试在beforeunload事件上调用axios

removeUser (id) {
    let payload = {
        locked_by: '',
        id: id
    }
    this.updateIsLockedField(payload).then(() => {
        console.log('updated')
        return 'something'
    })
},

我需要在用户关闭选项卡时发布API

没有可靠的方法在选项卡/窗口关闭时执行某些操作。这违反了“关闭”选项卡的原则,即释放资源

我处理您的情况的方法是让前端在选项卡关闭时自行保存一些东西


或者打开一个websocket,您可以将其用于许多其他目的,当它死掉并且在几秒钟内没有返回时,您就知道客户端已断开连接,或者在选项卡打开时发送一个常规ping,当它错过一些ping时,您可以安全地假定客户端已断开连接。

尝试通过向
open
方法传递false来发出同步请求:
xhr.open('PUT',Url,false)


因此,Vuejs为您提供了多个钩子,其中一个是destroyed,如果vue实例关闭,将调用此钩子,在任何情况下,包括browser closed,例如:

destroyed() {
    callYourFunctionName
}
我目前使用的系统与您的系统相同,我们需要在用户离开时解锁数据,经过多次搜索,不幸的是,无法保证您的函数将在浏览器关闭前结束其逻辑。如果您的函数请求稍有延迟,它可能无法工作=/

在这里,我们在destroyed()hook中进行了第一次尝试,我们的应用程序还有第二个安全因素,可以在afk用户10分钟后解锁任何寄存器


希望它有帮助

没有100%可靠的方法来做你想做的事情;浏览器选项卡可以以各种方式关闭,而您的代码没有任何机会运行。(考虑到电源可能会断开。)通常,通过将时间限制与每个锁相关联来解决这类问题。对于这一点,什么是好的方案?从后端和前端的角度来看,您无法100%知道选项卡何时关闭,但您可以监视选项卡是否仍然打开。您的接口需要每x次发送xhr请求以刷新锁移除的冷却时间。是的,我建议您可以像@iguypouf所说的那样每x次命中一个端点。您可以更新数据库中类似“last_active_at”的字段,如果该字段在60秒内未更新,则可以解锁。我不会执行任何类型的客户端解决方案。在服务器上获取锁可以通过首先移除任何已停用超过某个选定时间(可能10分钟)的锁来进行。然后,如果仍然有一个活动锁,则尝试失败-无论如何,您必须处理它。如果没有激活的锁,则尝试成功。锁处于活动状态时的每个后续操作都应该更新时间戳。我想你是对的,当用户断开连接时,我需要使用WebSocket来侦听事件。
removeUser () {
    var params = JSON.stringify({ locked_by: '' });
    let xhr = new XMLHttpRequest()
    xhr.open('PUT',Url, false) // `false` makes the request synchronous
    xhr.setRequestHeader("Authorization", 'Bearer ' + localStorage.getItem('app_access_token'))
    xhr.setRequestHeader("Content-length", params.length);
    xhr.setRequestHeader("Content-type", "application/json; charset=utf-8")
    xhr.responseType = 'arraybuffer'
    xhr.onreadystatechange = function() {//Call a function when the state changes.
    if(xhr.readyState == 4 && xhr.status == 200) {
        alert(xhr.responseText);
    }
}
destroyed() {
    callYourFunctionName
}