我在使用Chrome 81时,如果Web服务器开启了HTTP认证,包括基本认证与摘要认证,通过Chrome直接输入url,会弹出对话框,要求用户输入用户名和密码,如果用户名密码都正确,则可以正常访问,这是因为浏览器会自己通过header向服务器发送认证信息。
但如果需要通过ajax访问该url,执行代码xhr.open(method, url, async, username, password),并不能通过HTTP的401认证,无论是服务器要求基本认证还是摘要认证,都无法通过,我明明传了用户名和密码呀?换用IE 11,无论是摘要认证还是基本认证,都能完美通过,这点还是不错的。
没办法,Chrome是当前主流浏览器,必须要兼容啊,既然有些浏览器没有实现,就自己实现吧,代码中做了兼容,如果是IE本身支持ajax的HTTP认证,则JS中自己的认证不会生效,而在Chrome中则会使用自己实现的认证流程。
代码中用到了md5.js,请自行下载。
调用方法:
HttpAuth.ajax({
type: "POST", //请求类型,GET或POST
url: "http://ip:port/path/interfaceName", //请求地址
authType: "Digest", //认证类型,支持Diget与Basic,为空会自动判断
username: "user1", //用户名
password: "123456", //密码
data: {name:"我本有心", "gender":"男"}, //POST数据
contentType: "application/json; charset=UTF-8", //Content-Type
context: this, //回调函数上下文
success: function () { //成功回调
console.log("401 success");
},
error: function () { //失败回调
console.log("401 error");
},
complete: function () { //完成回调,无论成功或失败都会执行
console.log("401 complete");
}
});
实现代码如下:
var HttpAuth = {
ajax: function (settings) {
/*
settings与$.ajax使用方式相同
{
url : "http://ip:port/path", //请求地址
type: "POST", //请求方式,默认GET
async: false, //是否异步,默认true
data : "", //发送到服务器的数据
username: "", //用户名
password: "", //密码
timeout: 3000, //超时时间,毫秒
contentType: "application/json; charset=UTF-8", //请求类型
context: window, //回调函数上下文
success : function(result) { //请求成功回调函数
console.log(result);
},
error: function(xhr) { //请求失败回调函数
console.log(xhr);
},
complete: function(xhr) { //请求完成后回调函数 (请求成功或失败之后均调用)
console.log(xhr);
},
headers: {key1: "value1", key2: "value2"} //请求时需要附加的Header
authType: "Digest", //认证类型,"Digest"或"Basic"
}
*/
var method = settings.type ? settings.type.toUpperCase() : "GET";
var url = settings.url;
var async = settings.hasOwnProperty("async") ? settings.async : true;
var username = settings.username ? settings.username : "";
var password = settings.password ? settings.password : "";
var urlMD5 = this._md5(url);
var dataStr = "";
if (typeof settings.data == "string") {
dataS