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

Posted

技术标签:

【中文标题】使用 XmlHttpRequest 时是不是有任何方法可以抑制浏览器在 401 响应中的登录提示【英文标题】:Is there ANY way to suppress the browser's login prompt on 401 response when using XmlHttpRequest使用 XmlHttpRequest 时是否有任何方法可以抑制浏览器在 401 响应中的登录提示 【发布时间】:2010-09-26 13:31:30 【问题描述】:

我正在使用 jQuert .ajax 函数来调用页面方法。该站点正在使用 FormsAuthentication。因此,当身份验证票证到期时,对 page 方法的调用显然会导致重定向到登录页面。

现在,编写 System.Web.Handlers.ScriptModule 的天才们决定,如果出于某种原因,从 javascript 对页面方法或 Web 服务方法的 REST 样式调用导致 302 重定向,他们将只只需将响应变成 401 Unauthorized。这会导致浏览器弹出一个完全误导的登录 UI,因为用户尝试输入他们的用户名和密码,这没有任何意义,因为使用了 FormsAuthentication。最后,当用户单击“取消”时,401 将传递给错误处理程序。

那么,问题是,如何以任何方式禁用浏览器的登录 UI 提示?网上有人建议在 XHR 请求中使用用户名和密码,但似乎不起作用。

【问题讨论】:

【参考方案1】:

我想我已经解决了。当然,依靠内部的 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";
    

【讨论】:

我不太明白。你在服务器上做些什么来把你的 401 变成 200?如果您不使用 microsoft stack 或者您无权访问服务器,这将无济于事。我需要一个仅浏览器的解决方案。 嗯,问题 是特定于使用 Microsoft 堆栈的,解决方案仅适用于浏览器。不知道你的具体问题是什么。【参考方案2】:

这可以在 IIS 中禁用。下面描述的详细信息适用于 IIS6,但不难找到适用于 IIS7 及更高版本的相关项目。

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

您应该不再在浏览器中看到弹出窗口,并且能够根据需要发回正确的状态代码。

【讨论】:

【参考方案3】:

两者都是很好的答案。但是,如果您的网站托管在共享服务器中,您可能无法更改 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”,还有after a bit research,它似乎是一个头告诉服务器你正在做的请求是一个异步回发请求。

AJAX 调用将在“错误”回调中返回 HTTP 状态 200(而不是“未授权”401),这意味着服务器请求以某种方式成功(尽管身份验证失败)。有点奇怪,但它的工作方式就是这样。

希望这会有所帮助。

【讨论】:

添加标题 "X-MicrosoftAjax" : "Delta=true" 似乎解决了我获取 BASIC 登录提示的问题。

以上是关于使用 XmlHttpRequest 时是不是有任何方法可以抑制浏览器在 401 响应中的登录提示的主要内容,如果未能解决你的问题,请参考以下文章

HTTP 状态码 0 是不是有任何意义?

检索跨浏览器 XmlHttpRequest 的最简单方法

允许 Google Chrome 使用 XMLHttpRequest 从本地文件加载 URL

我无法使用 AJAX (XMLHttpRequest) 获取 responseXML

XMLHttpRequest Level 2 - 确定上传是不是完成

如何判断 XMLHTTPRequest 是不是命中浏览器缓存