javascript - how to silently guarantee executing an ASP.NET MVC3 action on page unload - Stack Overflow

I need to execute an action of a controller when a user leave a page (close, refresh, go to link, etc.)

I need to execute an action of a controller when a user leave a page (close, refresh, go to link, etc.). The action code is like:

public ActionResult WindowUnload(int token)
    {
        MyObjects[token].Dispose();
        return Content("Disposed");
    }

On window download I do Ajax request to the action:

$(window).unload(function ()
{
    $.ajax({
        type: "POST",
        url: "@Url.Action("WindowUnload")",
        data: {token: "@ViewData["Token"]"},
        cache: false,
        async: true
    });
    //alert("Disposing.");
})

The above ajax request does not e to my controller, i.e., the action is not executed. To make the code above to work I have to unment the alert line, but I don't want to fire alert on a user.

If I change async option to false (alert is mented), then it sometimes works. For example, if I refresh the page several times too fast then the action will not be executed for every unload.

Any suggestions how to execute the action on every unload without alert? Note, I don't need to return anything from action to the page.

Updated: answers summary

It is not possible reliably to do request on unload, since it is not proper or expected behavior on unload. So it is better to redesign the application and avoid doing HTTP request on window unload. If it is not avoidable, then there are mon solutions (described in the question):

  1. Call ajax synchronously, i.e., async: false.
    • Pros: works in most cases.
    • Pros: silent
    • Cons: does not work in some cases, e.g, when a user refreshes the windows several times too fast (observed in Firefox)
  2. Use alert on success or after ajax call
    • Pros: seems to work in all cases.
    • Cons: is not silent and fires pop up alert.

I need to execute an action of a controller when a user leave a page (close, refresh, go to link, etc.). The action code is like:

public ActionResult WindowUnload(int token)
    {
        MyObjects[token].Dispose();
        return Content("Disposed");
    }

On window download I do Ajax request to the action:

$(window).unload(function ()
{
    $.ajax({
        type: "POST",
        url: "@Url.Action("WindowUnload")",
        data: {token: "@ViewData["Token"]"},
        cache: false,
        async: true
    });
    //alert("Disposing.");
})

The above ajax request does not e to my controller, i.e., the action is not executed. To make the code above to work I have to unment the alert line, but I don't want to fire alert on a user.

If I change async option to false (alert is mented), then it sometimes works. For example, if I refresh the page several times too fast then the action will not be executed for every unload.

Any suggestions how to execute the action on every unload without alert? Note, I don't need to return anything from action to the page.

Updated: answers summary

It is not possible reliably to do request on unload, since it is not proper or expected behavior on unload. So it is better to redesign the application and avoid doing HTTP request on window unload. If it is not avoidable, then there are mon solutions (described in the question):

  1. Call ajax synchronously, i.e., async: false.
    • Pros: works in most cases.
    • Pros: silent
    • Cons: does not work in some cases, e.g, when a user refreshes the windows several times too fast (observed in Firefox)
  2. Use alert on success or after ajax call
    • Pros: seems to work in all cases.
    • Cons: is not silent and fires pop up alert.
Share Improve this question edited Dec 17, 2013 at 10:05 Marek Musielak 27.2k8 gold badges75 silver badges81 bronze badges asked Oct 24, 2011 at 12:38 k_rusk_rus 3,2291 gold badge23 silver badges36 bronze badges 1
  • What are you tring to achieve? There may be a better/ more robust way of getting to your end goal than this. – Russ Cam Commented Oct 24, 2011 at 13:25
Add a ment  | 

7 Answers 7

Reset to default 3

According to unload documentation, with async: false it should work as expected. However, this will always be a bit shaky - for example, user can leave your page by killing/crashing the browser and you will not receive any callback. Also, browser implementations vary. I fear you won't get any failproof even.

HTTP is stateless and you can never get a reliable way to detect that the user has left your page.

Suggested events:

  • Session timeout (if you are using sessions)
  • The application is going down
  • A timer (need to be bined with the previous suggestion)
  • Remove the previous token when a new page is visited.

Why does this need to happen at all?

From the code snippet you posted you are attempting to use this to dispose of objects server side? You are supposed to call Dispose to free up any un-managed resources your objects are using (such as Database connections).

This should be done during the processing of each request. There shouldn't be any un-managed resources awaiting a dispose when the client closes the browser window.

If this is the way you are attempting this in the manner noted above the code needs to be reworked.

Have you tried onbeforeunload()?

$(window).bind('beforeunload', function() 
    { 
        alert('unloading!'); 
    } 
);

or

window.onbeforeunload = function() {
    alert('unloading!'); 
}

From the ment you made to @Frazzell's answer it sounds like you are trying to manage concurrency. So on the chance that this is the case here are two mon method for managing it.

Optimistic concurrency

Optimistic concurrency adds a timestamp to the table. When the client edits the record the timestamp is included in the form. When they post their update the timestamp is also sent and the value is checked to make sure it is the most recent in the table. If it is, the update succeeds. If it is not then someone else got in sooner with an update so it is discarded. How you handle this is then up to you.

Pessimistic concurrency

If you often experience concurrency clashes then pessimistic concurrency may be better. Here when the client edits the record a flag is set on that row to lock it. This will remain until the client pletes the edit and no other user can edit that row. This method avoids users loosing changes but add an administration over head to the application. Now you need a way to release unwanted locks. You also have to inform the user through the UI that a row is locked for edit.

In my experience it is best to start with optimistic concurrency. If I have lots of people reporting problems I will try to find out why people are having these conflicts. It maybe that I have to break down some entities in to smaller types as they have bee responsible for doing too many jobs.

This wont work and even if you are able to somehow make it work it will give you lots of headaches later on, because this is not how the browser/HTTP is supposed to be used. When the page is unloading (in browser) the browser will call the unload event and then unload the page (you cannot make it wait, not even my making sync ajax calls) and in case the call was going on and the browser after executing the code unload the page, the call will also get cancelled and thats why you see the call on server sometimes and sometimes it doesn't work. If you could tell use why you want to do this we could suggest you a better approach.

You can't. The only thing you can do is prompt the user to stay and hope for the best. There are a whole host of security concerns here.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744677922a4587443.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信