AJAX POST 卸载处理程序在 ASP.NET 60 秒后不工作

AJAX POST to handler on unload not working after 60 seconds in ASP.NET

在 ASP.NET 中,我在页面上使用 jQuery AJAX 卸载到 POST 到 http 处理程序。这按预期工作——AJAX 在页面卸载时触发...除非我在页面上停留的时间超过 60 秒。之后,当页面关闭时,AJAX POST 似乎没有访问服务器。它在我的本地主机上工作正常,但在我们的开发或质量检查环境中却不行。

当处理程序被调用时,Fiddler 要么什么都不显示,要么给我一个通用的 401。我写了一个简单的测试脚本来使用 AJAX 每 30 秒 ping 服务器一次,以防我们遇到某种超时或 NTLM 令牌即将过期,但没有骰子。我们可以在服务器上看到 ping,但我们根本看不到服务器上的 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
}

关于为什么会发生这种情况,有什么想法或可能的解释吗?

答案是关闭这个 AJAX POST 的异步请求,所以看起来像这样:

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

由于 this question 以及我们有时在服务器端得不到 request/response 的事实,我怀疑 AJAX 调用在页面关闭之前没有完成。

据我了解,关闭异步通常不是一个好主意,尤其是在页面正在卸载时,因此请对此持保留态度。我们已确定此解决方案适用于我们的 Intranet 应用程序。