admin管理员组

文章数量:1356960

I'm stuck in a scenario need input from you guys. Currently, I'm working on a feature which is to lock the booking for other admins. I created a field inside the bookings table where I put the user_id when an admin es inside the booking that fields get updated with the current admin ID and other admins do have access to that booking at the moment.

So the problem is If the user closes the tab the booking remains locked for other admins as well.

I tried many different ways in vueJs such as beforeunload Method. I have used Xhr methods and axios both are failed in this condition. What else I can do to fix this issue

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);
mounted() {
    window.addEventListener('beforeunload', this.removeUser)

also tried the axios call on beforeunload event

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

I need to post the API when the user closes the tab

I'm stuck in a scenario need input from you guys. Currently, I'm working on a feature which is to lock the booking for other admins. I created a field inside the bookings table where I put the user_id when an admin es inside the booking that fields get updated with the current admin ID and other admins do have access to that booking at the moment.

So the problem is If the user closes the tab the booking remains locked for other admins as well.

I tried many different ways in vueJs such as beforeunload Method. I have used Xhr methods and axios both are failed in this condition. What else I can do to fix this issue

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);
mounted() {
    window.addEventListener('beforeunload', this.removeUser)

also tried the axios call on beforeunload event

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

I need to post the API when the user closes the tab

Share Improve this question edited Jul 31, 2019 at 12:57 Douwe de Haan 6,7063 gold badges33 silver badges52 bronze badges asked Jul 31, 2019 at 12:53 Syed Ameer HamzaSyed Ameer Hamza 631 silver badge10 bronze badges 5
  • There is no 100% reliable way to do what you're trying to do; the browser tab can close in various ways without your code having any chance of running. (Consider that the power might fail.) Generally that sort of problem is solved by associating a time limit with each lock. – Pointy Commented Jul 31, 2019 at 12:56
  • What will be a good scenario for this? From backend and front-end perspective – Syed Ameer Hamza Commented Jul 31, 2019 at 12:58
  • You cant 100% know when a tab is closed, but you can monitor if the tab is still open. Your interface needs to send xhr request every x time to refresh the cooldown of lock removal. – iguypouf Commented Jul 31, 2019 at 13:00
  • Yep I would suggest you could hit an endpoint every x time like @iguypouf says. You can update a field in a db that's something like 'last_active_at' and if that hasn't been updated for e.g. 60 seconds, then unlock. – party-ring Commented Jul 31, 2019 at 13:02
  • I wouldn't do any sort of client-side solution. Acquiring a lock at the server can proceed by first removing any locks that have been inactive for more than some chosen amount of time (10 minutes maybe). Then if there's still an active lock, the attempt fails — you have to handle that anyway. If there is no active lock, the attempt succeeds. Every subsequent action while the lock is active should update the timestamp. – Pointy Commented Jul 31, 2019 at 13:12
Add a ment  | 

3 Answers 3

Reset to default 7

There is no reliable way to execute something on tab/window close. It is against the very principle of "closing" the tab i.e. freeing up resources.

The way I would handle your situation is to have the frontend hold something that dies on it own when the tab closes.

Either open a websocket which you can use for many other purposes, and when it dies and does not e back within a few seconds you know that the client is disconnected, or send a regular ping while the tab is open and when it has missed a few pings you can safely assume the client is disconnected.

Try to make a synchrone request by passing a false to the open method : xhr.open('PUT',Url, false)

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);
    }
}

So, Vuejs offers you multiple hooks, one of them is the destroyed, this hook will be called if the vue instance is closed, by any case, that includes browser closed, something like:

destroyed() {
    callYourFunctionName
}

I'm current working on a system same as yours, we need to unlock data when user leaves, after much search, unfortunately, there is no way to garantee that your function will end its logic before browser closesm if you function request take a little delay, it probably wont work =/.

Here, we do this first try in destroyed() hook, and our application has a second security factor that unlock any register after 10 min afk user.

Hope it helps

本文标签: javascriptI want to POST data to an API when user close the browser tabStack Overflow