Last week I discovered a bug where, after session timeout, any ajax request would be automatically redirected back to the
Login
action. The ajax request would then 'blow up' on the client. I easily reproduced the bug by deleting cookies and attempting a new ajax request. Then I thought I had solved the problem with the following code combination.
Client:
$.acme.global.dataAccess = function() {
var dataAccess = {};
Object.defineProperty(this, "httpHeaderAjax", { value: "Acme-Is-Ajax-Request", writeable: true });
var defaultHeaders = {};
defaultHeaders[httpHeaderAjax] = true;
dataAccess.genericErrorFunction = function (response) {
if (response.status == 401) {
var returnUrl = location.pathname + location.search;
location.href = "/Account/Login?returnUrl=" + encodeURIComponent(returnUrl);
}
else if (!(response.status == 302) && !(response.status == 0) &&!(response.status==200)) {
location.href = "Error/?exceptionMessage=" + response.responseText;
}
};
dataAccess.submitAjaxPostJsonRequestWithErrorFunction = function (targetUrl, jsonData, successFunction, errorFunction) {
var jsonString = JSON.stringify(jsonData);
$.ajax({
type: 'POST',
url: targetUrl,
data: jsonString,
headers: defaultHeaders,
crossDomain: true,
success: successFunction,
error: errorFunction,
contentType: "application/json",
dataType: 'json'
});
};
return dataAccess;
}();
Server:
public class AccountController: BaseController
{
[AllowAnonymous]
public ActionResult Login(string ReturnUrl = "")
{
var ajaxHeader = Request.Headers[HttpConstants.RequestHeaders.ThreeFifteenIsAjaxRequest] ?? "false";
if (ajaxHeader == "true")
{
return new HttpUnauthorizedResult("Ajax request was redirected to Login action.");
}
if (ReturnUrl == "/Home/LogOff")
{
ReturnUrl = "/";
}
return View(AuthenticationProvider.Providers(ReturnUrl));
}
}
This works fine on my local machine, and on our dev environment, an Azure Web Site, but when I deploy it to our staging site, another Azure Web Site, the ajax problem is still unresolved. Putting a browser break-point in
genericErrorFunction
shows an expected 401 response locally and on dev, but on staging all I can see on the response object are the functions set by the ajax call.
Nothing in the code above seems to be environment dependent - it feels pretty hard and explicit to me - but I am desperately looking for possible explanations here.