I am trying to do a post to server before unloading a page and I followed this and it's working fine. My problem is the $.post on window.unload is triggered after it has unloaded. I tried it with a signout link and checking on my logs, I get the following:
Started GET "/signout" for 127.0.0.1 at 2012-11-22 00:15:08 +0800
Processing by SessionsController#destroy as HTML
Redirected to http://localhost:3000/
Completed 302 Found in 1ms
Started GET "/" for 127.0.0.1 at 2012-11-22 00:15:08 +0800
Processing by HomeController#index as HTML
Rendered home/index.html.erb within layouts/application (0.4ms)
Rendered layouts/_messages.html.erb (0.1ms)
Completed 200 OK in 13ms (Views: 12.9ms)
Started POST "/unloading" for 127.0.0.1 at 2012-11-22 00:15:08 +0800
Processing by HomeController#unloading as */*
Parameters: {"p1"=>"1"}
WARNING: Can't verify CSRF token authenticity
Completed 500 Internal Server Error in 0ms
NoMethodError (undefined method `id' for nil:NilClass):
app/controllers/home_controller.rb:43:in `unloading'
First part is the signout and then user gets redirected to root then it runs the post ('/unloading').
Is there a way to make the '/unloading' execute first then execute whatever the unload action was?
I have this as my jquery post
$(window).unload ->
$.ajax {
async: false,
beforeSend: (xhr) ->
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
, url: '/unloading'
, type: 'Post'
, data: {
p1: '1'
}
}
Update
So I did transfer the ajax request to beforeunload and it was working but I had to do a return null
to remove the dialog box appearing because if I don't, the ajax was still triggering on popup of dialog (even without answering "yes/no i want to leave this page"). Result is this:
window.onbeforeunload ->
$.ajax {
async: false,
beforeSend: (xhr) ->
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
, url: '/unloading'
, type: 'Post'
, data: {
p1: '1'
}
}
return null
Also, I have only tried it with Chrome for now and it's working as expected. Yet to try on other browsers.
I am trying to do a post to server before unloading a page and I followed this and it's working fine. My problem is the $.post on window.unload is triggered after it has unloaded. I tried it with a signout link and checking on my logs, I get the following:
Started GET "/signout" for 127.0.0.1 at 2012-11-22 00:15:08 +0800
Processing by SessionsController#destroy as HTML
Redirected to http://localhost:3000/
Completed 302 Found in 1ms
Started GET "/" for 127.0.0.1 at 2012-11-22 00:15:08 +0800
Processing by HomeController#index as HTML
Rendered home/index.html.erb within layouts/application (0.4ms)
Rendered layouts/_messages.html.erb (0.1ms)
Completed 200 OK in 13ms (Views: 12.9ms)
Started POST "/unloading" for 127.0.0.1 at 2012-11-22 00:15:08 +0800
Processing by HomeController#unloading as */*
Parameters: {"p1"=>"1"}
WARNING: Can't verify CSRF token authenticity
Completed 500 Internal Server Error in 0ms
NoMethodError (undefined method `id' for nil:NilClass):
app/controllers/home_controller.rb:43:in `unloading'
First part is the signout and then user gets redirected to root then it runs the post ('/unloading').
Is there a way to make the '/unloading' execute first then execute whatever the unload action was?
I have this as my jquery post
$(window).unload ->
$.ajax {
async: false,
beforeSend: (xhr) ->
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
, url: '/unloading'
, type: 'Post'
, data: {
p1: '1'
}
}
Update
So I did transfer the ajax request to beforeunload and it was working but I had to do a return null
to remove the dialog box appearing because if I don't, the ajax was still triggering on popup of dialog (even without answering "yes/no i want to leave this page"). Result is this:
window.onbeforeunload ->
$.ajax {
async: false,
beforeSend: (xhr) ->
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
, url: '/unloading'
, type: 'Post'
, data: {
p1: '1'
}
}
return null
Also, I have only tried it with Chrome for now and it's working as expected. Yet to try on other browsers.
Share Improve this question edited May 23, 2017 at 12:16 CommunityBot 11 silver badge asked Nov 22, 2012 at 4:58 indexindex 3,7277 gold badges40 silver badges56 bronze badges3 Answers
Reset to default 9 +100Try the beforeUnload
event
The exact handling of the unload event has varied from version to version of browsers. For example, some versions of Firefox trigger the event when a link is followed, but not when the window is closed. In practical usage, behavior should be tested on all supported browsers, and contrasted with the proprietary beforeunload event.
- https://developer.mozilla.org/en-US/docs/DOM/window.onbeforeunload
UPDATE
The unload event is triggered when the page has unloaded.
- https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Synchronous_and_Asynchronous_Requests#XMLHttpRequests_being_stopped
UPDATE 2
To disable the Are you sure that you want to leave this page?
popup try returning null
from the beforeUnload
callback function
- How to show the "Are you sure you want to navigate away from this page?" when changes committed?
UPDATE 3
Check this for cross-browser compatiblity
- http://jonathonhill.net/2011-03-04/catching-the-javascript-beforeunload-event-the-cross-browser-way/
As @NickKnudson suggested, use the "beforeUnload" event to post back form data before the window is unloaded:
window.onbeforeunload = function() {
$.ajax {
async: false,
beforeSend: (xhr) ->
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
, url: '/unloading'
, type: 'Post'
, data: {
p1: '1'
}
}
}
Ran into exact the same situation about two weeks ago, switching to beforeUnload solved the problem.
The problem is that the window's unload
event does not wait for AJAX calls (which are asyncrhonous) to complete prior to closing the window. In addition, jQuery doesn't seem to have built-in handling for the beforeunload
event - which is why you will need to revert to native JS code to handle this. See below:
(Note: Written in CoffeeScript)
window.onbeforeunload = function() {
$.ajax {
async: false, // Important - this makes this a blocking call
beforeSend: (xhr) ->
xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
, url: '/unloading'
, type: 'Post'
, data: {
p1: '1'
}
}
};
onbeforeunload - An event that fires before the unload event when the page is unloaded.
Also see this Google Forum discussion about this topic.