Ответ 1
Я нашел некоторые ресурсы об этом (см. нижнюю часть ответа) и перепутал следующее решение:
во время выполнения ajax-запроса я указал, что хочу вернуть json:
$.ajax({
url: action,
type: 'POST',
dataType: 'json',
data: jsonString,
contentType: 'application/json; charset=utf-8',
success:
function (result, textStatus, xhr) {
}
});
Поскольку моя платформа обрабатывает аутентификацию, а токен истекает, он передает HTTP-статус 302 в ответ. Поскольку я не хочу, чтобы мой браузер обрабатывал 302 ответ прозрачно, я его поймал в Global.asax и изменил статус на 200 OK. Кроме того, я добавил заголовок, который инструктирует меня обработать такой ответ особым образом:
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 302
&& (new HttpContextWrapper(Context)).Request.IsAjaxRequest())
{
Context.Response.StatusCode = 200;
Context.Response.AddHeader("REQUIRES_AUTH", "1");
}
}
Содержимое ответа не правильно сериализовано для json, что приводит к ошибке синтаксического анализа. Вызывается событие ошибки, внутри которого выполняется перенаправление:
$(document).ready(function () {
$.ajaxSetup({
error: function (XMLHttpRequest, textStatus, errorThrown) {
if (XMLHttpRequest.getResponseHeader('REQUIRES_AUTH') === '1') {
// redirect to logon page
window.location = XMLHttpRequest.getResponseHeader('location');
}
// do sth else
}
});
});
Смотрите Как управлять запросом перенаправления после вызова jQuery Ajax и здесь Как вы работаете с запросами AJAX, когда пользователь сеанс истекает, или когда запрос завершается в 302 для получения дополнительных пояснений.
UPDATE:
Между тем, я понял, что новое решение, на мой взгляд, намного лучше, потому что оно может применяться ко всем запросам ajax из коробки (если они не переопределяют значение beforeSend):
$.ajaxSetup({
beforeSend: checkPulse,
error: function (XMLHttpRequest, textStatus, errorThrown) {
document.open();
document.write(XMLHttpRequest.responseText);
document.close();
}
});
function checkPulse(XMLHttpRequest) {
var location = window.location.href;
$.ajax({
url: "/Controller/CheckPulse",
type: 'GET',
async: false,
beforeSend: null,
success:
function (result, textStatus, xhr) {
if (xhr.getResponseHeader('REQUIRES_AUTH') === '1') {
XMLHttpRequest.abort(); // terminate further ajax execution
window.location = location;
}
}
});
}
Метод контроллера может быть самым простым:
[Authorize]
public virtual void CheckPulse() {}
Application_EndRequest()
остается прежним.