原生JS对接Flask接口报Unexpected end of JSON input错误如何解决
报错原因
XMLHttpRequest的onreadystatechange事件会在readyState每次发生变化时触发,readyState共有5种状态:
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成,且响应已就绪
你当前的代码没有判断readyState是否为4、也没有判断HTTP状态码是否正常,只要事件触发就直接执行JSON.parse(txt),当readyState为2、3时,responseText还没有接收完全甚至是空值,解析空/不完整的JSON字符串就会抛出Unexpected end of JSON input报错。等到readyState变为4时,响应内容完整,解析成功,所以页面最终能正常展示内容,仅控制台留下前面几次触发事件产生的报错。
修复方案
在onreadystatechange回调中首先判断readyState是否为4,同时可以增加HTTP状态码判断,确认请求成功后再解析JSON:
function encodeUser(user, password) { var token = user + ":" + password; var hash = btoa(token); return "Basic " + hash; } function login(resultElement) { result = document.getElementById(resultElement) u = document.getElementById("email").value; p = document.getElementById("password").value; let xhr = new XMLHttpRequest(); let url = config_baseurl + "/login" xhr.open("POST",url,true); xhr.setRequestHeader("Content-Type","application/json"); xhr.setRequestHeader("Authorization", encodeUser(u, p)); xhr.onreadystatechange = function() { // 新增判断:请求完成且HTTP状态码为2xx区间代表请求成功 if (this.readyState === 4 && this.status >= 200 && this.status < 300) { txt = this.responseText; respJson = JSON.parse(txt); result.innerHTML = 'response: ' + txt + '<br><br>token: ' + respJson.token; } }; xhr.send(); }
可选优化:可以给JSON.parse增加异常捕获,避免后端返回非预期格式内容时页面报错:
if (this.readyState === 4 && this.status >= 200 && this.status < 300) { txt = this.responseText; try { respJson = JSON.parse(txt); result.innerHTML = 'response: ' + txt + '<br><br>token: ' + respJson.token; } catch (e) { result.innerHTML = '响应格式错误:' + txt; console.error('JSON解析失败', e); } }
内容的提问来源于stack exchange,提问作者Stephen
相关产品推荐
相关产品推荐

