8

I'm using self.render to render a html template, which is dependent on the information received from the client via ajax in the def post() method like this:

class aHandler(BaseHandler):
    @tornado.web.authenticated
    def post(self):
        taskComp = json.loads(self.request.body)   
        if taskComp['type'] == 'edit':
            if taskComp['taskType'] == 'task':
                self.render(
                    "tasks.html",         
                    user=self.current_user,
                    timestamp='',
                    projects='',
                    type='',
                    taskCount='',
                    resName='')

However this does not redirect the user to the html page 'tasks.html'.

However I see in my console a status:

[I 141215 16:00:55 web:1811] 200 GET /tasks (127.0.0.1)

Where '/tasks' is an alias for tasks.html

Why wouldn't this be redirected?

Or how can data received from ajax, then be used to redirect to the tasks.html page along with all the parameters supplied in the above self.render request?

user94628
  • 3,641
  • 17
  • 51
  • 88

2 Answers2

10

"render" never redirects a visitor's browser to a different URL. It shows the browser the contents of the page you render, in this case the "tasks.html" template.

To redirect the browser:

@tornado.web.authenticated
    def post(self):
        self.redirect('/tasks')
        return

More info in the redirect documentation.

To redirect using an AJAX response, try sending the target location from Python to Javascript:

class aHandler(BaseHandler):
    @tornado.web.authenticated
    def post(self):
        self.write(json.dumps(dict(
            location='/tasks',
            user=self.current_user,
            timestamp='',
            projects='',
            type='',
            taskCount='',
            resName='')))

Then in your AJAX response handler in Javascript:

$.ajax({
  url: "url",
}).done(function(data) {
  var url = data.location + '?user=' + data.user + '&timestamp=' + data.timestamp; // etc.
  window.location.replace("http://stackoverflow.com");
});

More about URL encoding is at this answer.

Community
  • 1
  • 1
A. Jesse Jiryu Davis
  • 23,641
  • 4
  • 57
  • 70
  • You're not using the word "redirect" correctly. A "redirect" changes the address shown in the browser's address bar. What the function call "render" does is show the contents of "tasks.html" to the user. What are you trying to do? In what way does it not work? – A. Jesse Jiryu Davis Dec 15 '14 at 19:28
  • What I'm trying to do is, an ajax request is received from the client with the `id` of a specific task. I then want to 'send' the user to the tasks.html, which is populated with certain task data specific to that 'id' that I'm sending through as the parameters in the `self.render` method. – user94628 Dec 15 '14 at 19:36
  • 2
    Thanks for that.....So would I use `window.location.replace()` to replace with the new document as assigned in `var url`. Something like this, `window.location.replace(url);` and the ajax response could be in the `success` of the original ajax request sent to the server? – user94628 Dec 15 '14 at 22:56
  • how to redirect with headers included? – Nikhil VJ Aug 18 '20 at 07:13
0
from urllib.parse import urlencode, urljoin

def redirect(self, url, permanent=False, status=None):
    """Sends a redirect to the given (optionally relative) URL.
    If the ``status`` argument is specified, that value is used as the
    HTTP status code; otherwise either 301 (permanent) or 302
    (temporary) is chosen based on the ``permanent`` argument.
    The default is 302 (temporary).
    """
    if not url.startswith(settings.WEB_ROOT):
        url = urljoin(settings.WEB_ROOT, url)
    if self._headers_written:
        raise Exception("Cannot redirect after headers have been written")
    if not status:
        status = 301 if permanent else 302
    else:
        assert isinstance(status, int)
        assert 300 <= status <= 399
    self.set_status(status)
    
    # This does the redirect
    self.set_header("Location", urljoin(self.request.uri, url))

# Call it this way
self.redirect("/tasks?" + urlencode({  user=self.current_user, timestamp: '', projects: '', type: '', taskCount: '', resName: ''})
miigotu
  • 1,387
  • 15
  • 15