共计 2235 个字符,预计需要花费 6 分钟才能阅读完成。
导读 | 这篇文章主要介绍了原生 js XMLhttprequest 请求 onreadystatechange 执行两次的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教 |
最近做到一个页面需要兼容 IE,然后就写了一个原生 XMLhttprequest 请求
直接上错误代码
xmlHttp = new XMLHttpRequest(); | |
xmlHttp.open("post","https://baidu.com/mianxiang/baidu/biancheng"); | |
xmlHttp.setRequestHeader("Content-Type","application/json"); | |
xmlHttp.send(XXXXXXXXXX) ; | |
xmlHttp.onreadystatechange = function () {if(this.status==200){console.log("responseText",this.responseText); | |
} | |
}; |
在上面代码中,当 status == 200 的 console.log 内容每次请求,都会在控制台打印两次,也就是说里面的逻辑会被执行两次,百度了很多都没有发现相似问题,和具体解决办法。
xmlHttp = new XMLHttpRequest(); | |
xmlHttp.open("post","https://baidu.com/mianxiang/baidu/biancheng"); | |
xmlHttp.setRequestHeader("Content-Type","application/json"); | |
xmlHttp.send(XXXXXXXXXX) ; | |
xmlHttp.onreadystatechange = function () {if(xmlHttp.readyState == 4 && this.status==200){console.log("responseText",this.responseText); | |
} | |
}; |
最后偶然发现了和正确代码的差距,补上“xmlHttp.readyState == 4”
执行一次,问题解决。
分析,可能是因为在没有添加判断 readyState 时,当 options 预请求执行时,也会有一次状态码 200 的,所以会被执行两次,但是疑惑点是预请求不会返回数据,但是在打印时,两次打印都是有数据的。
查资料 + 请教大佬 = get 知识
知识:
此阶段确认 XMLHttpRequest 对象是否创建,并为调用 open()方法进行未初始化作好准备。
值为 0 表示对象已经存在,否则浏览器会报错--对象不存在。
此阶段对 XMLHttpRequest 对象进行初始化,即调用 open()方法,根据参数 (method,url,true) 完成对象状态的设置。
并调用 send()方法开始向服务端发送请求。值为 1 表示正在向服务端发送请求。
此阶段接收服务器端的响应数据。但获得的还只是服务端响应的原始数据,并不能直接在客户端使用。
值为 2 表示已经接收完全部响应数据。并为下一阶段对数据解析作好准备。
此阶段解析接收到的服务器端响应数据。
即根据服务器端响应头部返回的 MIME 类型把数据转换成能通过 responseBody、responseText 或 responseXML 属性存取的格式,为在客户端调用作好准备。
状态 3 表示正在解析数据。
此阶段确认全部数据都已经解析为客户端可用的格式,解析已经完成。
值为 4 表示数据解析完毕,可以通过 XMLHttpRequest 对象的相应属性取得数据。
这个时候再回顾之前为何执行两次 onreadystatechange,因为当 state 每次变化的时候都会执行到 onreadystatechange,其实是 readyState 每次变化都会有执行 onreadystatechange,因为我判断了 this.status == 200,所以当服务器响应了之后返回了 200 的状态码,才会执行 console.log(),才有上面的执行两次的问题。
至此问题解决!!!
