XMLHttpRequest遇非200状态码报错,登录验证请求异常咨询
这个问题我太熟悉了!本质原因是浏览器的HTTP请求API对“错误状态码”的处理逻辑和你预期的不一样,再加上浏览器本身会默认记录所有非2xx的请求状态,导致你明明写了状态处理,控制台还是会弹出错误提示。下面分两种常用的请求方式给你解决方案:
一、如果用的是fetch API
fetch的设计很特殊:它只会在真正的网络故障(比如断网、跨域被阻止)时才会触发Promise.reject,而像403、500这种HTTP错误状态码,它会让Promise正常resolve,但会把response.ok设为false。
你之前的代码可能没正确处理这种情况,导致后续逻辑出错,或者浏览器的默认日志让你误以为是代码报错。正确的处理方式是先判断状态,再决定如何处理,同时避免未捕获的Promise错误:
fetch('/your-login-endpoint', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ username: 'xxx', password: 'xxx' }) }) .then(async response => { // 先处理所有非2xx状态 if (!response.ok) { const errorMsg = await response.text(); // 或者response.json(),看后端返回格式 if (response.status === 403) { console.log('凭证错误,请重新输入'); // 这里可以加你的UI提示逻辑,比如弹出提示框 } else if (response.status === 500) { console.log('服务器内部错误,请稍后重试'); } // 手动抛出错误,让catch捕获(可选,根据你的逻辑需求) throw new Error(`Request failed with status ${response.status}: ${errorMsg}`); } // 登录成功的逻辑 const data = await response.json(); console.log('登录成功', data); // 跳转页面或其他操作 }) .catch(err => { // 处理真正的网络错误,或者上面手动抛出的错误 console.error('请求出错:', err); });
这样处理后,浏览器Console标签里就不会再出现你说的那个报错了(Network标签里还是会显示403/500的请求记录,这是正常的,属于浏览器的网络日志,不是代码错误)。
二、如果用的是XMLHttpRequest
如果你用的是传统的XHR,那要注意:onerror事件只会触发网络错误,而403、500这种HTTP错误会触发onload事件。所以你需要在onload里判断状态码,而不是依赖onerror:
const xhr = new XMLHttpRequest(); xhr.open('POST', '/your-login-endpoint'); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = function() { if (xhr.status === 200) { // 登录成功 const data = JSON.parse(xhr.responseText); console.log('登录成功', data); } else if (xhr.status === 403) { console.log('凭证错误'); } else if (xhr.status === 500) { console.log('服务器错误'); } }; // 这里的onerror只处理网络层面的错误,比如断网 xhr.onerror = function() { console.error('网络连接出错'); }; xhr.send(JSON.stringify({ username: 'xxx', password: 'xxx' }));
之前你可能把HTTP错误的处理放在了onerror里,导致没触发,反而浏览器记录了错误状态,现在调整到onload里判断状态码就可以解决。
关键提醒
浏览器的Network标签里始终会显示所有请求的状态码,包括403、500,这是正常的调试信息,不是代码错误。只有Console标签里出现的红底错误提示,才是需要你处理的代码层面问题。
内容的提问来源于stack exchange,提问作者Zac

