Introduction
We might have requirement where we are required to run some server side logic like Session Kills etc when a user closes his browser (using Alt+F4, browser close button, File-Exit click etc). As most of us know IE (or any other browser) does not provide us any way to recognize any client side browser related event (as said above) raised and hence this cannot be achieved from any direct way like catching an event or etc.
This can be handled by some simple workarounds/logics by using some ASP.NET features and some client side coding, Let us see this.
Background
We have some client side events like onBeforeUnload
, OnUnload
provided to us in JavaScript which are executed whenever a document is unloaded, this may be for a simple Response.Redirect
or any other post back raised for executing a server side event (like dropdown selection change or grid view binding events or any event raised from a runat=server control), So we can understand that this event is executed when ever the document is unloaded which includes the browser close also, Hence we can achieve this by just eliminating all the possible unloads from the browser close events. Practically this might be impossible to have a global variable/flag and setting it for all the server side controls client side events, so we are trying to use a generalized approach like write once and use anywhere type of code.
Using the code
ASP.NET provides us many controls which
have capability of executing server side events, but in general only two
controls <input type='submit'…
and <input type='image'…
has
the ability to submit a form to server, But what ASP does for us is, it
automatically creates a client side JavaScript function __doPostBack(eventTarget, eventArgument)
and two hidden fields namely __EVENTTARGET
and __EVENTARGUMENT
. Here for all the controls (other than submit and image) which require a post back, ASP calls this __doPostBack
function with the source controls id as the first argument and any required value as the second argument and as seen in the below function here the event raised controls id is stored in the __EVENTTARGET
hidden field and the page is submitted manually (you can check this function rendered on any of your webpage source when rendered onto a browser even you
are unaware of writing any code like this.
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit ();
}
}
Hence from the above description we can understand for any post back raised (other than
<input type='submit' …
and <input type='image'
) we can confirm that there exists some value (generally controls id) in the
__EVENTTARGET
hidden field.
We will use the above logic to achieve our requirement, please go through below steps:
- Include jQuery library into the aspx page which we are using:
<script src="../Js/jquery-1.7.min.js" type="text/javascript"></script>
- Declare some Global Variables for distinguishing the different types of post backs.
var isSubmitPostBack = false;
var isPostBack = false;var isJSRefresh = false;
- Bind a function to document. ready which sets the declared global variables if the page unload is taken place due to submit click or image click or an anchor click (anchor tags does
not submit the page but it creates a new GET or POST request to the specified server in the
href
attribute).
$(document).ready(function () {
$("input:submit").click(function () {
isSubmitPostBack = true;
});
$("input:image").click(function () {
isSubmitPostBack = true;
});
$('a:not(a[href^=javascript])').click(function () {
isSubmitPostBack = true;
});
});
- Bind a function to
window.onUnLoad
which checks the reason why the document is unloaded whether it is from
__doPostBack
or submit or image click or an anchor click.
Based on the condition if the unload is not due to any of the above mentioned reasons then open a new window using window. open method (because this opens a new window
which carries the same session as the parent window) where in the new page we can handle the events that are required to log out the user.
window.onunload = function() { LogOut(); }
function LogOut() {
var hdnSrcTarget = $("#__EVENTTARGET")[0];
if(hdnSrcTarget != null && hdnSrcTarget != 'undefined'){
if(hdnSrcTarget.value == '')
isPostBack = false;
else
isPostBack = true;
}
var condition = !(isSubmitPostBack || isPostBack || isJSRefresh)
if((refreshflag != 1 && condition) || logout==true || alterffourflag == 1){
var logOutWin = window.open("Logout.aspx", "childWindow","width=5,height=5,toolbar=no,<wbr />scrollbars=no,menubar=no");
logOutWin.blur();
}
}
Note: This whole logic can be kept in a Master Page or a Header user control which will be used in all the pages in your web project so that this functionality will be applicable to the whole application.
But here there are some exceptions or some browser side events which can also unload a page like browser refresh or clicking browser back button or changing the
URL and hitting Enter. These exceptions can be handled in the new window that is opened. For this follow the below steps:
- Create a new web page for handling Session killing events (LogOut.aspx in this case).
- Place a button on the page such that it would not be visible on the page.
<asp:Button ID="btnLogOut" runat="server" Text="" Style="width: 1px; height: 1px;" />
- Call a client side JavaScript function on loading the web page where we get the
parent window reference using window. Opener and using this we can check whether
the parent window is closed or not, if yes then click the invisible button using JavaScript which raises a server side event that handles all the Session killing logic.
function CloseWindow(){
window.opener = self;
window.close();
}
function LogOutSession(){
var parent = window.opener;
if(parent){
if(parent.closed){
var btn = document.getElementById('<wbr />btnLogOut');
btn.click();
}
else{
CloseWindow();
}
}
else{
CloseWindow();
}
}
History