• 0
Votes
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /var/www/html/cnasolution/site/application/views/question.php
Line: 191
Function: _error_handler

File: /var/www/html/cnasolution/site/application/controllers/Questions.php
Line: 419
Function: view

File: /var/www/html/cnasolution/site/index.php
Line: 315
Function: require_once

I'm using $.post() to call a servlet using Ajax and then using the resulting HTML fragment to replace a div element in the user's current page. However, if the session times out, the server sends a redirect directive to send the user to the login page. In this case, jQuery is replacing the div element with the contents of the login page, forcing the user's eyes to witness a rare scene indeed.

How can I manage a redirect directive from an Ajax call with jQuery 1.2.6?

Download script demo [LINK] [Origin]
Download script demo [LINK 2] [Onedrive] Download script demo [LINK 2] [Google drive]

I read this question and implemented the approach that has been stated regarding setting the response HTTP status code to 278 in order to avoid the browser transparently handling the redirects. Even though this worked, I was a little dissatisfied as it is a bit of a hack.

After more digging around, I ditched this approach and used JSON. In this case, all responses to AJAX requests have the status code 200 and the body of the response contains a JSON object that is constructed on the server. The JavaScript on the client can then use the JSON object to decide what it needs to do.

I had a similar problem to yours. I perform an AJAX request that has 2 possible responses: one that redirects the browser to a new page and one that replaces an existing HTML form on the current page with a new one. The jQuery code to do this looks something like:

$.ajax({     type: "POST",     url: reqUrl,     data: reqBody,     dataType: "json",     success: function(data, textStatus) {         if (data.redirect) {             // data.redirect contains the string URL to redirect to             window.location.href = data.redirect;         } else {             // data.form contains the HTML for the replacement form             $("#myform").replaceWith(data.form);         }     } }); 

The JSON object "data" is constructed on the server to have 2 members: data.redirect and data.form. I found this approach to be much better.

see demo
  • 25
Reply Report

I solved this issue by:

  1. Adding a custom header to the response:

    public ActionResult Index(){     if (!HttpContext.User.Identity.IsAuthenticated)     {         HttpContext.Response.AddHeader("REQUIRES_AUTH","1");     }     return View(); } 
  2. Binding a JavaScript function to the ajaxSuccess event and checking to see if the header exists:

    $(document).ajaxSuccess(function(event, request, settings) {     if (request.getResponseHeader('REQUIRES_AUTH') === '1') {        window.location = '/';     } }); 
demo
  • 33
Reply Report

No browsers handle 301 and 302 responses correctly. And in fact the standard even says they should handle them "transparently" which is a MASSIVE headache for Ajax Library vendors. In Ra-Ajax we were forced into using HTTP response status code 278 (just some "unused" success code) to handle transparently redirects from the server...

This really annoys me, and if someone here have some "pull" in W3C I would appreciate that you could let W3C know that we really need to handle 301 and 302 codes ourselves...! ;)

  • 45
Reply Report

The solution that was eventually implemented was to use a wrapper for the callback function of the Ajax call and in this wrapper check for the existence of a specific element on the returned HTML chunk. If the element was found then the wrapper executed a redirection. If not, the wrapper forwarded the call to the actual callback function.

For example, our wrapper function was something like:

function cbWrapper(data, funct){     if($("#myForm", data).length > 0)         top.location.href="login.htm";//redirection     else         funct(data); } 

Then, when making the Ajax call we used something like:

$.post("myAjaxHandler",         {         param1: foo,         param2: bar        },        function(data){            cbWrapper(data, myActualCB);        },         "html" ); 

This worked for us because all Ajax calls always returned HTML inside a DIV element that we use to replace a piece of the page. Also, we only needed to redirect to the login page.

  • 45
Reply Report

I like Timmerz's method with a slight twist of lemon. If you ever get returned contentType of text/html when you're expecting JSON, you are most likely being redirected. In my case, I just simply reload the page, and it gets redirected to the login page. Oh, and check that the jqXHR status is 200, which seems silly, because you are in the error function, right? Otherwise, legitimate error cases will force an iterative reload (oops)

$.ajax(    error:  function (jqXHR, timeout, message) {     var contentType = jqXHR.getResponseHeader("Content-Type");     if (jqXHR.status === 200 && contentType.toLowerCase().indexOf("text/html") >= 0) {         // assume that our login has expired - reload our current page         window.location.reload();     }  }); 
  • 39
Reply Report