使用 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 响应中的登录提示的主要内容,如果未能解决你的问题,请参考以下文章
允许 Google Chrome 使用 XMLHttpRequest 从本地文件加载 URL
我无法使用 AJAX (XMLHttpRequest) 获取 responseXML