我需要使用基本身份验证发送授权请求。我已经使用 jquery 成功实现了这一点。但是,当我收到 401 错误时,基本身份验证浏览器弹出窗口已打开并且未调用 jquery ajax 错误回调。
如何防止浏览器调用基本身份验证弹出窗口并使用 Jquery 处理 401 错误?
我最近也面临这个问题。由于您无法更改浏览器在401
(基本或摘要式身份验证)情况下显示弹出窗口的默认行为,因此有两种方法可以解决此问题:
- 将服务器响应更改为不返回
401
.200
而是返回一个代码并在您的 jQuery 客户端中处理它。 将您用于授权的方法更改为标头中的自定义值。浏览器将显示Basic和Digest的弹出窗口。您必须在客户端和服务器上更改此设置。
headers : { "Authorization" : "BasicCustom" }
另请查看此示例,以了解将 jQuery 与基本身份验证一起使用的示例。
返回一个通用的 400 状态代码,然后处理该客户端。
或者您可以保留 401,而不返回 WWW-Authenticate 标头,这实际上是浏览器通过身份验证弹出窗口响应的内容。如果缺少 WWW-Authenticate 标头,则浏览器将不会提示输入凭据。
您可以使用如下所示的请求 url 来抑制基本身份验证弹出窗口:
https://username:password@example.com/admin/...
如果您收到 401 错误(错误的用户名或密码),它将被 jquery 错误回调正确处理。它可能会导致一些安全问题(在 http 协议而不是 https 的情况下),但它有效。
UPD:此解决方案支持将在 Chrome 59 中删除
正如其他人指出的那样,更改浏览器行为的唯一方法是确保响应不包含 401 状态代码,或者如果包含,则不包含WWW-Authenticate: Basic
标题。由于更改状态代码不是很符合语义且不可取,因此删除WWW-Authenticate
标头是一个好方法。如果您不能或不想修改您的 Web 服务器应用程序,您始终可以通过 Apache 为其提供服务或代理(如果您尚未使用 Apache)。
这是 Apache 重写响应以删除 WWW-Authenticate 标头的配置,请求包含的 IFF 包含标头X-Requested-With: XMLHttpRequest
(默认情况下由 JQuery/AngularJS 等主要 Javascript 框架设置...)并且响应包含标题WWW-Authenticate: Basic
。
在 Apache 2.4 上测试(不确定它是否适用于 2.2)。这取决于mod_headers
正在安装的module。(在 Debian/Ubuntu 上,sudo a2enmod headers
并重新启动 Apache)
<Location />
# Make sure that if it is an XHR request,
# we don't send back basic authentication header.
# This is to prevent the browser from displaying a basic auth login dialog.
Header unset WWW-Authenticate "expr=req('X-Requested-With') == 'XMLHttpRequest' && resp('WWW-Authenticate') =~ /^Basic/"
</Location>
将 X-Requested-With: XMLHttpRequest 与您的请求标头一起使用。所以响应头将不包含 WWW-Authenticate:Basic。
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', ("Basic "
.concat(btoa(key))));
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
},