Sessions are destroyed by ajax calls?

1,304 views
Skip to first unread message

SergeyPo

unread,
Mar 5, 2009, 2:16:10 AM3/5/09
to web2py Web Framework
I have strange problem when trying to make ajax calls (all with jquery
supplied with web2py). After an Ajax call previously created session
becomes lost, and new empty session is created. I tried file storage
and db sessions storage, it does not matter. After ajax call, any
other call to the site creates new empty session.

There is an error message in request object, but I am not sure it's
relevant to this problem:
'wsgi_errors': <open file '<stderr>', mode 'w' at 0x170b0>

I am lost for 3 days with this problem! Where to look?

Here is complete request dump:
<Storage {'function': 'add_filter', 'body': <open file '<fdopen>',
mode 'w+b' at 0x65eff08>, 'cookies': <SimpleCookie:
_csuid='47dbd5bc37527d09' session_id_admin='127-0-0-1-4b36395a-
c90d-4b40-a359-42d9db303463' session_id_advantage='127-0-0-1-184830b9-
d184-4e60-8ec4-be367a7b5a56' session_id_welcome='127-0-0-1-
a5552de4-3c7b-4a9a-a93b-12b1ff15e66d'>, 'vars': <Storage {}>, 'args':
[], 'application': 'advantage', 'controller': 'radar', 'client':
'127.0.0.1', 'env': <Storage {'auth_type': '', 'content_length': '0',
'http_user_agent': 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6;
en-us) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/
525.27.1', 'script_name': '', 'actual_server_protocol': 'HTTP/1.1',
'server_protocol': 'HTTP/1.1', 'wsgi_errors': <open file '<stderr>',
mode 'w' at 0x170b0>, 'web2py_path': '/Users/vasilina/Documents/
_Development/ADVANTAGE/web2py', 'http_accept': '*/*',
'wsgi_url_scheme': 'http', 'http_x_requested_with': 'XMLHttpRequest',
'http_referer': 'http://127.0.0.1:8000/advantage/radar/grid/',
'remote_addr': '127.0.0.1', 'wsgi_multiprocess': False,
'http_accept_language': 'en-us', 'wsgi_version': (1, 0),
'request_method': 'POST', 'server_port': '8000', 'wsgi_input':
<gluon.wsgiserver.SizeCheckWrapper object at 0x63cd6b0>,
'wsgi_multithread': True, 'http_cookie': '_csuid=47dbd5bc37527d09;
session_id_admin=127-0-0-1-4b36395a-c90d-4b40-a359-42d9db303463;
session_id_advantage=127-0-0-1-184830b9-d184-4e60-8ec4-be367a7b5a56;
session_id_welcome=127-0-0-1-a5552de4-3c7b-4a9a-a93b-12b1ff15e66d',
'server_software': 'CherryPy/3.1.0beta3 WSGI Server',
'web2py_version': 'Version 1.57 (2009-03-01 22:04:03)\n', 'http_host':
'127.0.0.1:8000', 'path_info': '/advantage/radar/add_filter',
'content_type': 'application/xml', 'http_connection': 'keep-alive',
'server_name': 'Macintosh-2.local', 'remote_port': '49815',
'http_accept_encoding': 'gzip, deflate', 'query_string': '',
'wsgi_run_once': False}>, 'get_vars': <Storage {}>, 'folder': '/Users/
vasilina/Documents/_Development/ADVANTAGE/web2py/applications/
advantage/', 'now': datetime.datetime(2009, 3, 5, 10, 1, 19, 987188),
'post_vars': <Storage {}>}>

SergeyPo

unread,
Mar 5, 2009, 4:36:29 AM3/5/09
to web2py Web Framework
A bit more details:

this controller function is called by ajax:

def add_filter():
#append new custom object to list in session.filter
#Filter object contains only strings and dicts
session.filter.append(Filter())
#update session.filter list with some computations, it works
update_filter()
#generates HTML inputs and selects from session.filter list
filter_terms = prepare_filter()
return dict(filter_terms=XML(filter_terms))

at this point you can print session.filter and see valid contents;
also in session file you can see valid pickle representation of my
Filter object.

Resulting XML is rendered in browser DIV, as usually by Ajax call.

But after this, ANY call to the site (ajax or normal) generate new
session file or record in db if session storage is db. This new
session is of course empty, and application tries to use this new
session.

mdipierro

unread,
Mar 5, 2009, 8:33:24 AM3/5/09
to web2py Web Framework
Which browser? Can you print request.cookies and see if the ajax
request is sending the session cookies?

Massimo

SergeyPo

unread,
Mar 5, 2009, 8:48:33 AM3/5/09
to web2py Web Framework
Safari and FireFox on Mac, Fox and IE on Windows,
ajax sends only http-cookies, env cookies are empty


This is the printout from BEAUTIFY(request) - however I don't know how
to paste it retaining table structure:

application
:
advantage
args
:
body
:
<open file '<fdopen>', mode 'w+b' at 0x65a4530>
client
:
127.0.0.1
controller
:
radar
cookies
:
session_id_admin
:
comment
:
domain
:
expires
:
max-age
:
path
:
secure
:
version
:
session_id_advantage
:
comment
:
domain
:
expires
:
max-age
:
path
:
secure
:
version
:
session_id_welcome
:
comment
:
domain
:
expires
:
max-age
:
path
:
secure
:
version
:
env
:
actual_server_protocol
:
HTTP/1.1
auth_type
:
content_length
:
50
content_type
:
application/x-www-form-urlencoded
http_accept
:
*/*
http_accept_encoding
:
gzip, deflate
http_accept_language
:
en-us
http_connection
:
keep-alive
http_cookie
:
_csuid=47dbd5bc37527d09;
session_id_admin=127-0-0-1-9832558d-97dd-45da-96e9-8a9120ebc16e;
session_id_advantage=127-0-0-1-1bcf67ab-d123-4fe6-8367-cc61bff8bb12;
session_id_welcome=127-0-0-1-99f3a2dd-6b69-4bc8-be31-a5499bd87e7a
http_host
:
127.0.0.1:8000
http_referer
:
http://127.0.0.1:8000/advantage/radar/grid/
http_user_agent
:
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-us) AppleWebKit/
525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1
http_x_requested_with
:
XMLHttpRequest
path_info
:
/advantage/radar/add_filter
query_string
:
remote_addr
:
127.0.0.1
remote_port
:
50969
request_method
:
POST
script_name
:
server_name
:
Macintosh-2.local
server_port
:
8000
server_protocol
:
HTTP/1.1
server_software
:
CherryPy/3.1.0beta3 WSGI Server
web2py_path
:
/Users/vasilina/Documents/_Development/ADVANTAGE/web2py
web2py_version
:
Version 1.57 (2009-03-01 22:04:03)
wsgi_errors
:
<open file '<stderr>', mode 'w' at 0x170b0>
wsgi_input
:
<gluon.wsgiserver.SizeCheckWrapper object at 0x64ddc70>
wsgi_multiprocess
:
False
wsgi_multithread
:
True
wsgi_run_once
:
False
wsgi_url_scheme
:
http
wsgi_version
:
1
0
folder
:
/Users/vasilina/Documents/_Development/ADVANTAGE/web2py/applications/
advantage/
function
:
add_filter
get_vars
:
now
:
datetime.datetime(2009, 3, 5, 16, 45, 1, 965971)
post_vars
:
sid
:
127-0-0-1-1bcf67ab-d123-4fe6-8367-cc61bff8bb12
vars
:
sid
:
127-0-0-1-1bcf67ab-d123-4fe6-8367-cc61bff8bb12

SergeyPo

unread,
Mar 6, 2009, 1:19:24 AM3/6/09
to web2py Web Framework
I found other posts here with same problem, all unanswered. Please
reply do you have positive examples of jQuery sending cookies with
ajax?

I tried to pass session-id with hidden form field but get other
strange error.

Controller function (called by ajax):

from gluon.storage import Storage
def add_filter():
if request.vars.sid: #this is hidden field passing session id
mysession=Storage()
n = 'applications/%s/sessions/%s' %
('advantage',request.vars.sid)
print n #prints good address of session file
print 'mysession', mysession #prints # mysession <Storage {}>
mysession.load_storage(n) #breaks here, see below
session = mysession
session.filter.append(Filter())
update_filter()
filter_terms = prepare_filter()
return dict(filter_terms=XML(filter_terms))

Error traceback:
Traceback (most recent call last):
File "/Users/vasilina/Documents/_Development/ADVANTAGE/web2py copy/
gluon/restricted.py", line 98, in restricted
File "/Users/vasilina/Documents/_Development/ADVANTAGE/web2py/
applications/advantage/controllers/radar.py", line 293, in <module>
File "/Users/vasilina/Documents/_Development/ADVANTAGE/web2py/gluon/
globals.py", line 75, in <lambda>
self._caller = lambda f: f()
File "/Users/vasilina/Documents/_Development/ADVANTAGE/web2py/
applications/advantage/controllers/radar.py", line 239, in add_filter
mysession.load_storage(n)
TypeError: 'NoneType' object is not callable

So, mysession object is Storage object right before load_storage call,
and immediately becomes NoneType!

SergeyPo

unread,
Mar 6, 2009, 4:43:35 AM3/6/09
to web2py Web Framework
Sorry this is not spamming but I keep trying to fix problem with
sessions and javascript.
My site uses frames and this may lead to problems. For example the
following link from 'left' frame works (opens something in right
frame):

_onclick="javascript:top.frames['right'].location.reload()"

But this one - does not:

_onclick="javascript:top.frames['right'].location='/advantage/radar/
filter_by_cart/1'"

Here 'filter_by_cart' is name of controller. In this case web2py
looses session.

I found the following recipe:

http://petesbloggerama.blogspot.com/2007/08/aspnet-loss-of-session-cookies-with.html

briefly:
If you implement a FRAMESET where frames point to other Web sites on
the networks of your partners or inside your network, but you use
different top-level domain names, you may notice in Internet Explorer
6 that any cookies you try to set in those frames are lost. This is
most frequently experienced as a loss of session state in an Active
Server Pages (ASP) or ASP.NET Web application. You try to access a
variable in the Session object that you expect to exist, and it is
null.

The fix is very simple - Starting in Internet Explorer 6 support for
the Platform for Privacy Preferences (P3P) Project was introduced. The
P3P standard notes that if a FRAMESET or a parent window references
another site inside a FRAME or inside a child window, the child site
is considered third party content. Internet Explorer, which uses the
default privacy setting of Medium, silently rejects cookies sent from
third party sites.

You can add a P3P compact policy header to your child content, and you
can declare that no malicious actions are performed with the data of
the user. If Internet Explorer detects a satisfactory policy, then
Internet Explorer permits the cookie to be set.

A simple compact policy that fulfills the needed criteria follows:

P3P: CP="CAO PSA OUR"

The above code sample shows that your site provides you access to your
own contact information (CAO), that any analyzed data is only "pseudo-
analyzed", which means that the data is connected to your online
persona and not to your physical identity (PSA), and that your data is
not supplied to any outside agencies for those agencies to use (OUR).
This is sufficient to get Internet Explorer (and some other browsers)
to allow the Session cookie, as well as other cookies.

QUESTION, Massimo, how to add such a header to http headers?
(I really don't want time to rewrite the whole app without frames -
jQuery panes is good for small amounts of data but not for larger
tables that I need in my Intranet app).

mdipierro

unread,
Mar 6, 2009, 8:37:48 AM3/6/09
to web2py Web Framework
Fascinating. I think you are looking for:

response.headers['P3P']='CP="CAO PSA OUR"'

Massimo

On Mar 6, 3:43 am, SergeyPo <ser...@zarealye.com> wrote:
> Sorry this is not spamming but I keep trying to fix problem with
> sessions and javascript.
> My site uses frames and this may lead to problems. For example the
> following link from 'left' frame works (opens something in right
> frame):
>
> _onclick="javascript:top.frames['right'].location.reload()"
>
> But this one - does not:
>
> _onclick="javascript:top.frames['right'].location='/advantage/radar/
> filter_by_cart/1'"
>
> Here 'filter_by_cart' is name of controller. In this case web2py
> looses session.
>
> I found the following recipe:
>
> http://petesbloggerama.blogspot.com/2007/08/aspnet-loss-of-session-co...

SergeyPo

unread,
Mar 6, 2009, 10:02:05 AM3/6/09
to web2py Web Framework
Thank you Massimo,
however this did not help.

SergeyPo

unread,
Mar 9, 2009, 3:12:28 AM3/9/09
to web2py Web Framework
Problem solved:

that was not ajax or web2py fault. Sessions are broken when you try to
store any custom class (not only db-related class). Example:

class Klaas: pass
session.something = Klaas()
#this will be stored in session and in session file you will see
correct pickle representation of the object (NB!)

However, later in other calls this session won't be restored and
silently updated with new one. Therefore, several suggestions:
1. update docs to clearly say that no classes defined in your models
or controller files, can be stored in sessions
2. make some error diagnostic for this case, e.g. print to console
window
3. won't that be possible in the future (no hurry) to import classes
e.g. defined in models, to pickle environment, because now object
storing in sessions 'almost works' so why stop at half of the road?

Thank you for great product!

Fran

unread,
Mar 9, 2009, 3:49:08 AM3/9/09
to web2py Web Framework
On Mar 9, 7:12 am, SergeyPo <ser...@zarealye.com> wrote:
> session.something = Klaas()
> #this will be stored in session and in session file you will see
> correct pickle representation of the object (NB!)
> However, later in  other calls this session won't be restored and
> silently updated with new one.

Place this in your model to have your class always accessible:

def myapp_sessions(f):
session.something = Klaas()
return f()
response._caller=lambda f: myapp_sessions(f)

F

SergeyPo

unread,
Mar 9, 2009, 5:37:59 AM3/9/09
to web2py Web Framework
Thank you Fran,
it's a bit more abstract than I can understand: does it mean that if I
have many methods in my Klaas I need to make a number of such wrappers
for each method? Obviously I wanted to store custom class in session
because I needed to access class methods. Namely, I use session to
store a number of filters for db select: you can add filter e.g. 'by
name' and application would append new Filter object to array stored
in session; later this Filter object can be used to generate HTML form
snippets to edit filter values and SQL snippets to add to sql query.
Thus we have at least a constructor and two methods (getSQL and
getHTML).

mdipierro

unread,
Mar 9, 2009, 10:26:32 AM3/9/09
to web2py Web Framework
I am not convinced this works as you expect. This just makes a new
empty Klaas object at every call.
I will look into this.

Massimo
Reply all
Reply to author
Forward
0 new messages