Call ajax to clear session after user has left page - php

I want to clear the php session array every time a user leaves my page, but my page has links with query strings. I don't want to clear the session array, when a user clicks on a link with a query string. I have tried the following javascript code but it does not work when the user leaves the page.
somepage.php
var url = new RegExp(/somepage.php\?sort=.*/);
if (url.test(document.location.href)){
//do nothing
}
else {
$(window).unload(function(){
$.ajax({
url: 'clear_session.php'
});
});
}

Calling a webserivce onunload is very unrealiable. Why not just unset the PHPSESSID cookie? This wont clean up the session on the server, but it will give the user a new empty session when he visits again.

Related

Issue with AJAX Hashbang

I've came across a problem with using a 'hashbang' to keep track of which page has been loaded via AJAX.
When a link is clicked which loads content through an AJAX request into the content div, the hash of the URL changes to the page name. For example, if the user comes directly to pageA (http://www.domain.com/pageA) and then clicks a link for pageB, the URL will change to http://www.domain.com/pageA#/pageB
I'm using CodeIgniter for my application, and the code which handles the hash changing is in my header view, and it does the following:
<script type="text/javascript">
window.redirect = function() {
if(window.location.hash.substring(0, 2) == "#!") {
if(window.location.hash.substring(2).length > 2) {
window.location = window.location.hash.substring(2);
} else {
return false;
}
}
return false;
}
window.redirect();
</script>
<script type="text/javascript">
$(function() {
$(window).hashchange(function() {
if(ajax_loading == true) {
return false;
} else {
loadPage(window.location.hash.substring(2), 'internal', '');
}
});
});
</script>
There are two steps to this. The first one checks if there is a hashbang when coming directly to a page by refreshing, or entering the URL for example. If there is a hashbang, redirect to the page stored in the hash.
The second step checks for a change to the hash, which catches the likes of the user pressing the back button, for example.
My issue is with the first block - when a user refreshes or directly enters a URL with a hashbang.
If the user enters http://www.domain.com/pageA#/pageB, any server side code on pageA will run before the window is then redirected pageB
This is causing problems in cases such as:
User directly goes to pageA - pageA sets a session variable to 'abc'
User clicks on link to pageB - pageB then sets that session variable to 'xyz' - the URL is currently http://www.domain.com/pageA#/pageB
User clicks on link to pageC - the session variable is still set to 'xyz' and pageC doesn't change this - the URL is currently http://www.domain.com/pageA#/pageC
User now hits refresh. pageA is executed first, before redirecting to pageC - but because pageA was executed first, the session variable has now been set back to 'abc' when it should be 'xyz'.
Due to loading the views at the last point of the code within a CodeIgniter controller - I can't do the window redirect at any point other than when the code of the page before the hashbang has executed.
Does any have any ideas of how I can prevent this from happening?
Just don't send user to http://www.domain.com/pageA#/pageC.
You should have a unique page, that does not set any session variable, and load other pages via AJAX. Then users never goes directly to pageA but through http://www.domain.com/index#/pageA.
User goes to /index#/pageA - pageA sets a session variable to 'abc'
User clicks on link to pageB - pageB then sets that session variable to 'xyz' - the URL is currently http://www.domain.com/index#/pageB
User clicks on link to pageC - the session variable is still set to 'xyz' and pageC doesn't change this - the URL is currently http://www.domain.com/index#/pageC
User now hits refresh. index is executed first, before redirecting to pageC - but because index does not set anything, the session variable is now still 'xyz'.
As I suppose you provides yourself the links to the user, there should be no problem setting it up.

How to keep session alive without reloading page?

I have a strange problem in my online test management system.
Some users in the test form (test.php) need long time to answer the question and submit the form.
After submitting the form the session is expired and user must login again
this is not a code problem
I set this value in top of all pages
ini_set('session.gc_maxlifetime', 18000);
Is there a way to refresh the session evrey 10 minutes without reloading the page in test form to prevent session expire?
Please help me
Thanks
You can use javascript XHR, or as others call it, AJAX.
http://api.jquery.com/jQuery.ajax/
http://api.jquery.com/jQuery.get/
Using ajax you can call a php script that refreshes your session every 10 minutes. :)
This is as far as i can go to "exact".
javascript
var refreshSn = function ()
{
var time = 600000; // 10 mins
setTimeout(
function ()
{
$.ajax({
url: 'refresh_session.php',
cache: false,
complete: function () {refreshSn();}
});
},
time
);
};
// Call in page
refreshSn()
refresh_session.php
<?php
session_start();
// store session data
if (isset($_SESSION['id']))
$_SESSION['id'] = $_SESSION['id']; // or if you have any algo.
?>
Anyway, another solution would be to extend the session time for the test page only using
the solution presented here
How do I expire a PHP session after 30 minutes?
All you need is this (uses jQuery for the $.post):
JavaScript (put this inside your onload-function or something)
setInterval(function(){
$.post('path/to/refresh_session.php');
},600000); //refreshes the session every 10 minutes
refresh_session.php
<?php
session_start();
// if you have more session-vars that are needed for login, also check
// if they are set and refresh them as well
if (isset($_SESSION['token'])) {
$_SESSION['token'] = $_SESSION['token'];
}
?>
The biggest change is in the JavaScript--you don't need a whole function, just one line.
EXTRA INFO
Although I think it's enough to just call session_start() in the php, if I read this right (http://nl3.php.net/function.session-start):
The read callback will retrieve any existing session data (stored in a
special serialized format) and will be unserialized and used to
automatically populate the $_SESSION superglobal when the read
callback returns the saved session data back to PHP session handling.
And during testing I only put the above code on my visitor page, and not on the admin page. But I had both pages open in the same browser (Chrome), and the admin page stayed logged in as well, at least for over an hour (didn't check any longer).
BUT, I don't know if it still works if you only use session_start(), without manually refreshing any session-var at all..
Either way, I like to be sure that the session-vars I need are really still there:)
Javascript:
function doStayAlive() {
var request = new XMLHttpRequest();
request.open('GET', 'stayalive.php', true);
request.send();
}
timerStayAlive = setInterval(doStayAlive, 600000); // 10 minutes
PHP: (stayalive.php)
<?php
session_start();
http_response_code(204);
?>
There is no need to "touch" session variables

PHP+AJAX (jQuery) - Reading session data on $.post() return

I am currently writing an "Edit Account" module. Using jQuery.post(); I can successfully update my database, and I can write to the session variables from the PHP script - however,
when trying to access the Session variable that I just wrote to, the data does not seem to have been updated.
I write to the session like this: $_SESSION['email'] = 'john#doe.com'; in my Ajax.php
My jQuery (minified) callback on success:
$.post(...,function(res)
{
if(res=='success')
{
// Alert the new E-Mail, read from the Session!
alert("<?php echo $_SESSION['email']; ?>");
}
}
However, the alert does not output john#doe.com, it outputs whatever the E-Mail was it was when the entire page was loaded. When I refresh the page, the session data has been properly updated.
I do have session_start(); on both index.php (my site) and in Ajax.php
If you need more info please do let me know. :)
First of all it should be
alert("<?php echo $_SESSION['email']; ?>");
and secondly $.post is dynamic but <?php echo $_SESSION['email']; ?> is static. It renders once, on load, not everytime you make an .post() so if
$_SESSION['email'] = 'blah'; by the time the page is loaded, the alert will always be alert("blah"); , until you reload the page.
If you want to alert the new session variable you have to make a new ajax request to a php file (ie. return_session.php?key=email ), that will return the new session variable
Thats because the alert string is generated when the page is loaded. And when you make an ajax request it still doesnt change, because its not refreshed.
On ajax success you should output the responseText and then it will work.

How to use $.post to be included in request of a new page

I'm working on cookie-free session, I dont intend to pass variables through URL, but I try to use window.name or hidden forms. For window.name, I'd do mosething like this:
$(window).unload(function(){
if(location.href.indexOf(<my pages base url>) != -1){
// the user is going to my site
if($.parseJSON(window.name).previous_site.indexOf(location.protocol + '/' + location.host) != -1){
// now I know, that user was of my site
cookie_alternative = new Object();
cookie_alternative.previous_site = location.href;
cookie_alternative.session_id = $.parseJSON(window.name).session_id; // this is important
.....
window.name = $.toJSON(cookie_alternative);
}
else{
// the user was elsewhere
cookie_alternative = new Object();
cookie_alternative.previous_site = location.href;
cookie_alternative.session_id = <something new>;
.....
window.name = $.toJSON(cookie_alternative);
}
}
else{
//the user goes somewhere else
window.name = '';
}
});
So I can track session_id this way. I suppose I'd do something similar to this, if I was to use hidden input field. And now, I want this variable (session_id) from window.name to act as if it was cookies - user clicks on some link, which takes him to different part of my web => the request is sent to the server, server responds and page is displayed. With this request I want to send session_id to server using post (as if it was a cookie)- but I can't figure out, how to do this. I was thitking about something like this:
$('a').click(function(){
$.post({
url: $(this).attr('href'),
data: $.parseJSON(window.name).session_id,
})
})
but I don't think it's going to work, and as I said, I'm not going to use URL rewriting. Other way to do this would propably be to have some hidden form type post, click on link sets form's action (href of a link), sets data: session_id and triggers form's action.
Any ideas to send post to follow next pages request? Or how to use hidden form field to achieve the same thing? Any help really appreciated..
$('a').click(function(e){
//Preventing link from triggering
e.preventDefault();
var elObj = $(e.currentTarget);
$('#secret-hidden-form').attr('action',elObj.attr('href'));
$('#secret-hidden-form').submit();
return false;
})
At the bottom of your page:
<?php
if (isset($_POST['session_id']) {
$sessId = $_POST['session_id']
} else {
$sessId = uniqid();
}
?>
<form id="secret-hidden-form" method="post">
<input type="hidden" value="<?php echo $sessId; ?>">
</form>
Maybe something like this will work?
You can get data to the server with each page request via cookies, URL query parameters or by posting form data.
Maintaining a session across every link on your site without cookies will require a javascript override of every single URL the user visits on your site to either turn it into a form post with sessionID in the form or to add query parameters with sessionID. How practical this is depends upon how many places on your site, you have to override things.
If I were implementing a session without cookies, I'd use URL rewriting (ideally server-side) so every URL in the page either all goes through a common JS function that adds the session ID before processing the click or just rewrites the ID into the URL so the normal click can just happen and it will have the session in the URL. This allows you to preserve most of your navigation and server-side logic, but moves the sessionID from cookie to URL. Of course, this won't be persistent from one user session to the next unless the user bookmarks a URL with the sessionID in it so users will have to re-establish a session everytime they come to your site.

Create a session before an ajax call

I have this website where I can interact with the web both as a logged or anonymus user. When I click a link I call an ajax function:
you click here:
<a id="alcrearuta" class="'.$row->urlamigable.'" href="#">aƱadir a ruta</a>
This is my ajax function:
var valor=$("#alcrearuta").attr('class');
$("#alcrearuta").click(function(){
$.ajax({
type: "GET",
url: "../ajax/ruta.php",
data: "urlamigable=" + valor,
dataType: 'html',
success: function(data) {
$("#listaruta").html(data);
}
});
});
The thing is I have two possibilities: either a logged user clicks the link and the ruta.php does its stuff on the database considering the userid that's set in the session or I have an anonymous user that wants to do something similar.
In my ruta.php I have:
if(!empty($_SESSION['Username'])){
//Insert stuff on DB
}else{
//I wish I could create the session here but I can't since it's an ajax call
}
What I need is at some point between the click in the link and the end of the ajax function I can set my $SESSION['Username'] variable to get a new value (since the user it's not logged in, it's currently empty and thus my inserts on the database not working)
if you want to use sessions in php, your php script (ruta.php) schould start with
session_start();
from that point you can assign any variable to $_SESSION['Username']
$_SESSION['Username'] = something_to_generate_a_Username;
Just like any other server request.
You could use jquery cookie library to create a session cookie.
$.cookie("Username", "NOTLOGGEDINUSER");
https://github.com/carhartl/jquery-cookie
http://www.electrictoolbox.com/jquery-cookies/
and in beforeSend for Ajax, you can check if username cookie exists, other wise, create the cookie with "NOTLOGGEDINUSER"
Maybe on the click do another AJAX call just to set the SESSION?

Categories