使用jQuery.ajax发起GET请求遇401 Unauthorized,XMLHttpRequest正常
从你的代码来看,两者核心逻辑看似一致,但jQuery.ajax的一些默认行为或内部处理细节,可能是导致问题的关键。下面是几个最可能的原因:
1. 全局配置覆盖了自定义请求头
jQuery有全局的$.ajaxSetup()配置,如果你的项目中之前通过它设置过Authorization头或其他全局请求规则,那你在单个ajax请求里定义的headers很可能会被全局配置覆盖。而原生XMLHttpRequest完全独立,不受这些全局设置影响,所以能正常发送你指定的头。
你可以试试在请求里加上global: false禁用全局钩子,验证是否是这个问题:
jQuery.ajax({ url: url1, headers: { "Authorization": "Basic Auth"}, dataType: "json", type: "GET", timeout: 190000, global: false, // 禁用全局ajax事件与配置 success: response3 });
2. jQuery对Authorization头的隐性处理
先提个小细节:标准Basic Auth头的格式应该是Basic [base64编码的用户名:密码](比如Basic dXNlcjE6cGFzc3dvcmQ=),你写的"Basic Auth"其实不符合规范。不过既然原生XHR能正常运行,说明服务器对这个头的校验比较宽松(比如只检查是否包含Basic关键字)。
但jQuery可能在内部对Authorization头做了格式校验,或者在跨域等场景下自动调整这个头,导致服务器无法识别,返回401。你可以尝试换成标准格式的头内容,看看jQuery请求是否恢复正常。
3. jQuery自动添加的额外请求头触发了服务器限制
jQuery.ajax默认会给请求加上X-Requested-With: XMLHttpRequest头,用来标识这是AJAX请求。如果你的服务器权限验证逻辑中,对带有这个头的请求有额外限制(比如未配置允许该头跨域,或把它标记为非信任请求),就会返回401。而原生XHR默认不会添加这个头,所以能顺利通过校验。
你可以尝试在jQuery请求中移除这个头:
jQuery.ajax({ url: url1, headers: { "Authorization": "Basic Auth", "X-Requested-With": null // 移除默认添加的头 }, dataType: "json", type: "GET", timeout: 190000, success: response3 });
4. jQuery的自动认证弹窗干扰了请求
当jQuery收到401响应时,可能会自动触发浏览器的原生认证弹窗——哪怕你已经手动设置了Authorization头。这个过程会重置或覆盖你设置的头,导致后续请求依然失败。而原生XHR不会自动触发这个弹窗,直接返回响应,所以你的代码能正常处理。
你可以试试添加xhrFields: { withCredentials: false },或者在error回调里手动处理错误,阻止浏览器弹窗:
jQuery.ajax({ url: url1, headers: { "Authorization": "Basic Auth"}, dataType: "json", type: "GET", timeout: 190000, xhrFields: { withCredentials: false }, success: response3, error: function(xhr) { if(xhr.status === 401) { // 手动处理错误,避免浏览器弹出认证窗口 console.log("权限验证失败"); } } });
内容的提问来源于stack exchange,提问作者irs102info

