有没有任何方法可以在使用XmlHttpRequest时抑制浏览器在401响应时的登录提示框?

8
我正在使用jQuery的.ajax函数来调用一个页面方法。该网站正在使用FormsAuthentication。因此,当身份验证票证过期时,调用页面方法显然会导致重定向到登录页面。
现在,编写System.Web.Handlers.ScriptModule的天才们决定,如果由于某种原因从JavaScript对页面方法或Web服务方法进行REST风格的调用导致302重定向,他们将简单地将响应转换为401未经授权。这会导致浏览器弹出一个完全误导用户的登录UI,因为用户试图输入他们的用户名和密码,但这些信息是无效的,因为使用了FormsAuthentication。最终,当用户点击取消时,就会传递401给错误处理程序。
因此,问题是,如何以任何方式禁用浏览器的登录UI提示?一些网上的人建议在XHR请求中使用用户名和密码,但似乎并不起作用。
3个回答

5
我想我已经解决了这个问题。当然,依赖于内部MS AJAX相关错误并不是很好,但对于其他面临此问题的人来说,这将起到作用。
基本上,你所做的就是将 X-MicrosoftAjax 头设置为值 Delta = true (大小写很重要),ScriptModule将把此解释为正常重定向,并将响应转换为 200 ,但将为页面上的任何ScriptManager(MS-AJAX PageRequestManager)设置 pageRedirect 数据字符串以供使用。jQuery.ajax函数仍将此视为错误,因此您可以在XHR的responseText属性中检查 pageRedirect 并相应地处理它。例如,将用户发送到登录页面。
    $.ajax({
            type: "POST",
            url: postUrl + "/SomePageMethod",
            data: "{searchString:\"" + escape(searchString) + "\"}",
            contentType: "application/json; charset=utf-8",
            beforeSend: function(xhr) {
                xhr.setRequestHeader("X-MicrosoftAjax","Delta=true");
            },
            dataType: "json",
            success: onSuccess,
            error: onError
        });

function onError(xhr, e, textStatus) {
    var isAjaxRedirect = xhr.status == 200 && xhr.responseText.match(/pageRedirect/);
    if (isAjaxRedirect == "pageRedirect") {
        // forms authentication ticket expired
        location.href = "a session timeout page, or a login page or whatever";
    }
}

1
我不太明白。你是在服务器上做一些事情来将你的401转换为200吗?如果你没有使用微软堆栈或者没有访问服务器,那么这并没有什么帮助。我需要一个仅限于浏览器的解决方案。 - Landon Kuhn
1
问题是针对使用Microsoft技术栈的特定情况,并且解决方案仅限于浏览器。不过,我不清楚你具体遇到了什么问题。 - Strelok

2

这可以在IIS中禁用。以下详细说明适用于IIS6,但应该很容易找到IIS7及更高版本的相关项目。

  1. 找到相关站点。
  2. 打开“目录安全性”选项卡或您的IIS版本中的相关选项卡
  3. 在“身份验证和访问控制”部分内单击“编辑”
  4. 取消选中“集成Windows身份验证”

您将不再看到浏览器中的弹出窗口,并且能够按照您的意愿发送回正确的状态代码。


1
这是两个很好的答案。但是如果您的网站托管在共享服务器上,则可能无法更改IIS设置,因此客户端解决方案最为适用。 我曾经遇到过同样的问题,这篇文章帮了我大忙。我的建议是: 在jquery中(至少在最新版本中),您可以使用一个名为“header”的参数来发送这些标题信息,而不必使用“beforeSend”回调函数。我认为这可能是一种更加简洁的方法,也可以在此处添加其他标题信息:
$.ajax({
            type: "POST",
            url: postUrl + "/SomePageMethod",
            data: "{searchString:\"" + escape(searchString) + "\"}",
            contentType: "application/json; charset=utf-8",
        headers: { "cache-control": "no-cache", "X-MicrosoftAjax" : "Delta=true" },
            dataType: "json",
            success: onSuccess,
            error: onError
        });

我不知道关于“Delta=true”这个头部的信息,经过一些研究,它似乎是一个头部,用于告诉服务器您正在进行异步回传请求。 在“错误”回调中,AJAX调用将返回HTTP状态200(而不是401“未经授权”),这意味着服务器请求在某种程度上成功了(尽管身份验证失败)。有点奇怪,但这就是它的工作方式。 希望这可以帮到您。

添加头部 "X-MicrosoftAjax" : "Delta=true" 似乎解决了我遇到的基本登录提示问题。 - Callum Luke Vernon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接