AJAX POST для обработчика при выгрузке не работает через 60 секунд в ASP.NET

В ASP.NET я использую jQuery AJAX на странице, выгружаемой в POST обработчику http. Это работает, как и ожидалось - AJAX срабатывает при выгрузке страницы... если только я не остаюсь на странице более 60 секунд. После этого, когда страница закрыта, AJAX POST, похоже, не попадает на сервер. Он отлично работает на моем локальном хосте, но не в нашей среде разработки или контроля качества.

Fiddler либо ничего не показывает, либо выдает общий код 401 при вызове обработчика. Я написал простой тестовый скрипт, чтобы использовать AJAX для проверки связи с сервером каждые 30 секунд на случай, если мы получим какой-то тайм-аут или срок действия токена NTLM истекает, но не кости. Мы можем видеть пинг на сервере, но мы вообще не можем видеть AJAX POST на сервере, если он не запущен до истечения 60 секунд.

Вот AJAX POST. Первоначально он просто использовал jQuery.post(), но я хотел попробовать установить для withCredentials значение true, чтобы увидеть, была ли проблема в этом (это не помогло).

jQuery(window).bind("unload.audit", function () {
    jQuery.ajax({
        type: "POST",
        url: "IndicativeDataAuditHandler.axd?HasUnsavedChanges=" + _hasUnsavedChanges() + "&PageTitle=" + document.title,
        xhrFields: { withCredentials: true }
    });
});

Вот запись обработчика в Web.config:

<add name="IndicativeDataAuditHandler" path="IndicativeDataAuditHandler.axd" 
     verb="POST, HEAD" type="Namespace.Namespace, App_Code" preCondition="integratedMode"/>

А вот (важные части) код обработчика. Он вызывает объект CSLA.

public class IndicativeDataAuditHandler : IHttpHandler, IRequiresSessionState
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        try
        {
            var applicationID = new Guid(ConfigurationManager.AppSettings["ApplicationID"]);
            var referrerUrl = context.Request.UrlReferrer.ToString();
            IndicativeDataAuditLogCommand.InsertAuditLog(applicationID, GetPageTitle(context), referrerUrl, GetHasUnsavedChanges(context), GetPartyID(context), GetUserID(context));
        }
        catch(Exception ex)
        {
            throw new Exception("Failed to send indicative data edit request log.", ex);
        }
    }
    //Some private methods here to get parameters
}

Любые идеи или возможные объяснения относительно того, почему это может происходить?


person Daniel Miller    schedule 01.12.2015    source источник


Ответы (1)


Ответ заключался в отключении асинхронных запросов для этого AJAX POST, так что это выглядит так:

jQuery.ajax({
    type: "POST",
    async: false,
    url: "IndicativeDataAuditHandler.axd?HasUnsavedChanges=" + _hasUnsavedChanges() + "&PageTitle=" + document.title,
    xhrFields: { withCredentials: true }
});

Из-за этого вопроса и тот факт, что мы иногда не получали запрос/ответ на стороне сервера, я подозревал, что вызов AJAX не завершался до закрытия страницы.

Насколько я понимаю, зачастую отключать асинхронность — плохая идея, особенно когда страница выгружается, так что относитесь к этому с недоверием. Мы определили, что это решение приемлемо для нашего приложения для интрасети.

person Daniel Miller    schedule 04.01.2016