Bug Tracker

Opened 8 years ago

Closed 8 years ago

Last modified 5 years ago

#9155 closed bug (cantfix)

AJAX Headers not persisting in Firefox when Redirected (301 / 303). Chrome, Chromium, Safari and IE works Ok.

Reported by: ygbr Owned by:
Priority: undecided Milestone: 1.next
Component: ajax Version: 1.6
Keywords: Cc:
Blocked by: Blocking:

Description

When you issue a AJAX Request of any kind using JQuery (tested with 1.5.2 and 1.6), the HTTP Headers don't persist to the next request.

When you send the first request using Firefox (tested on 3.x and 4.0.1 stable), the server receives the {'X-Requested-With': 'XMLHttpRequest'} or any other Headers you may set on your AJAX request, then when it returns a 301 response, the next request made to the server don't replicate the HTTP Headers (not even the X-Requested-With).

On Chrome, Chromium, Safari and IE, the Headers are replicated back to the server after the 301/303 redirect responses, generating a 200 response with the correct http request headers.

Follows a small python client/server script that demonstrates the problem.

#!/usr/bin/env python3.2
# -*- coding: utf-8 -*-

import cherrypy

class App:
    
    @cherrypy.expose
    def index(self):
        return '''<!doctype>
<html>
    <head>
        <title>Yg test</title>
    </head>
    
    <body>
        <form action='/process' method='post'>
            <input type='text' name='username' placeholder='User' /><br/>
            <input type='text' name='email' placeholder='Email' /><br/>
            <input type='submit' value='Enviar' />
        </form>
    </body>
</html>'''

    @cherrypy.expose
    def redirme(self, **kwargs):
        raise cherrypy.HTTPRedirect('/getme')
    
    @cherrypy.expose
    def getme(self):
        return str(cherrypy.request.headers)
    
    @cherrypy.expose
    def index(self):
        return '''
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
        
        <div id='res'></div>
        
        <input type='button' id='bt1' value='Direct Request (No Redirection)' /> 
        <input type='button' id='bt2' value='Redirected (301) Request - No X-Requested-With HTTP Header Persisted' />
        
        <script>
            $(document).ready(function(){
                $('#bt1').click(function(){
                    $('#res').load('/getme');
                });
            
                $('#bt2').click(function(){
                    $('#res').load('/redirme');
                });
            });
        </script>
'''
        
cherrypy.quickstart(App(), '/')

And the responses using Firefox:

# DIRECT REQUEST (without server-side 301/303 redirections):
{'Remote-Addr': '127.0.0.1', 'Accept-Language': 'en-us,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Keep-Alive': '115', 'Connection': 'keep-alive', 'Accept': 'text/html, */*; q=0.01', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Host': 'localhost:8080', 'Cookie': 'session_id=057fef543d4197e2caf7c170f04a11601bb7a382', 'Referer': 'http://localhost:8080/', 'X-Requested-With': 'XMLHttpRequest'}

# REDIRECTED REQUEST (server returns a 301 Redirect):
{'Remote-Addr': '127.0.0.1', 'Accept-Language': 'en-us,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Keep-Alive': '115', 'Connection': 'keep-alive', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Host': 'localhost:8080', 'Referer': 'http://localhost:8080/', 'Cookie': 'session_id=057fef543d4197e2caf7c170f04a11601bb7a382'}

as you can see, X-Requested-With is present only on the Direct Request.

Now look the behavior of all other browsers (Using Chromium to demonstrate):

# DIRECT REQUEST (without server-side 301/303 redirections):
{'Remote-Addr': '127.0.0.1', 'Accept-Language': 'en-US,en;q=0.8', 'Accept-Encoding': 'gzip,deflate,sdch', 'Connection': 'keep-alive', 'Accept': 'text/html, */*; q=0.01', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/534.32 (KHTML, like Gecko) Chrome/13.0.751.0 Safari/534.32', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Host': 'localhost:8080', 'Cookie': 'session_id=c111ecec6c49475cfd0b3adb92657e7f296e6e52', 'Referer': 'http://localhost:8080/', 'X-Requested-With': 'XMLHttpRequest'}

# REDIRECTED REQUEST (server returns a 301 Redirect):
{'Remote-Addr': '127.0.0.1', 'Accept-Language': 'en-US,en;q=0.8', 'Accept-Encoding': 'gzip,deflate,sdch', 'Connection': 'keep-alive', 'Accept': 'text/html, */*; q=0.01', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit/534.32 (KHTML, like Gecko) Chrome/13.0.751.0 Safari/534.32', 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', 'Host': 'localhost:8080', 'Cookie': 'session_id=c111ecec6c49475cfd0b3adb92657e7f296e6e52', 'Referer': 'http://localhost:8080/', 'X-Requested-With': 'XMLHttpRequest'}

Clearly there is a serious problem on Firefox (3 and 4) and JQuery AJAX Requests when you get redirects.

Is this a jQuery bug or a Firefox one???

Change History (6)

comment:1 Changed 8 years ago by ygbr

Sorry for the duplicated index method declaration on my python snippet... it is safe to disregard the first index method declaration and remove it, leaving only the last one (altought it will run normally as the last one superseeds the previous).

Follows the code reviewed:

#!/usr/bin/env python3.2
# -*- coding: utf-8 -*-

import cherrypy

class App:
    
    @cherrypy.expose
    def redirme(self, **kwargs):
        raise cherrypy.HTTPRedirect('/getme')
    
    @cherrypy.expose
    def getme(self):
        return str(cherrypy.request.headers)
    
    @cherrypy.expose
    def index(self):
        return '''
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
        
        <div id='res'></div>
        
        <input type='button' id='bt1' value='Direct Request (No Redirection)' /> 
        <input type='button' id='bt2' value='Redirected (301) Request - No X-Requested-With HTTP Header Persisted' />
        
        <script>
            $(document).ready(function(){
                $('#bt1').click(function(){
                    $('#res').load('/getme');
                });
            
                $('#bt2').click(function(){
                    $('#res').load('/redirme');
                });
            });
        </script>
'''
        
cherrypy.quickstart(App(), '/')

comment:2 Changed 8 years ago by ygbr

Also tested on Opera 11.01 - Mac OS X 10.6.4 - It also behaves correctly!

comment:3 Changed 8 years ago by ygbr

It seems to be a Firefox XHR bug... Do you guys think of any workaround or are we expected to remove all server side redirects in order to work properly with Firefox?

Follows the bugzilla link for this bug: https://bugzilla.mozilla.org/show_bug.cgi?id=553888

comment:4 Changed 8 years ago by jaubourg

Resolution: cantfix
Status: newclosed

I'm afraid we'll have to wait for firefox to get a fix. We have no control whatsoever on the internals of the native xhr :/

comment:5 Changed 8 years ago by jaubourg

Component: unfiledajax

comment:6 Changed 5 years ago by miketaylr

In case anybody is looking at this years later like me, this was fixed in Gecko.

Note: See TracTickets for help on using tickets.