搜索

查看: 3116|回复: 11

[JavaScript] 原生js XMLhttprequest请求onreadystatechange执行两次的解决

[复制链接]
发表于 2023-5-4 11:46:41 | 显示全部楼层 |阅读模式
Editor 2023-5-4 11:46:41 3116 11 看全部
目录
  • 原生js XMLhttprequest请求onreadychange执行两次
  • 关于readyState不同状态总结
  • (0) 未初始化
  • (1) 载入
  • (2) 载入完成
  • (3) 交互
  • (4) 完成
  • 总结
    原生js XMLhttprequest请求onreadychange执行两次
    最近做到一个页面需要兼容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之前readystate值为0,调用open()之后就变为1了,并且此时onreadystatechange函数与open()几乎是同时执行的。
  • 在之后调用send方法之后,在startHttpRequest函数中readystate值仍为1,而调用send方法之后应该有2,3,4三个状态,而只有在startHttpRequest函数用alert语句才可以观察到3个值!
  • 这是为什么呢?这是因为在startHttpRequest函数中当解析到send这一句时,并没有真正开始执行send执行。
  • 只有send执行,才可以在onreadystatechange函数观察到状态值的变化。
  • readystate不是发送的状态,它是准备发送的状态,要把它想像成“人间大炮一级准备、二级准备、放”这样的口号,不是请求发送本身。
  • 同时xmlhttp也不是监听服务器信息,它是在send的时候获取服务器返回的状态信息而已,只有一次,监听则是一直在观察状态。
    关于readyState不同状态总结
    (0) 未初始化
    此阶段确认XMLHttpRequest对象是否创建,并为调用open()方法进行未初始化作好准备。
    值为0表示对象已经存在,否则浏览器会报错--对象不存在。

    (1) 载入
    此阶段对XMLHttpRequest对象进行初始化,即调用open()方法,根据参数(method,url,true)完成对象状态的设置。
    并调用send()方法开始向服务端发送请求。值为1表示正在向服务端发送请求。

    (2) 载入完成
    此阶段接收服务器端的响应数据。但获得的还只是服务端响应的原始数据,并不能直接在客户端使用。
    值为2表示已经接收完全部响应数据。并为下一阶段对数据解析作好准备。

    (3) 交互
    此阶段解析接收到的服务器端响应数据。
    即根据服务器端响应头部返回的MIME类型把数据转换成能通过responseBody、responseText或responseXML属性存取的格式,为在客户端调用作好准备。
    状态3表示正在解析数据。

    (4) 完成
    此阶段确认全部数据都已经解析为客户端可用的格式,解析已经完成。
    值为4表示数据解析完毕,可以通过XMLHttpRequest对象的相应属性取得数据。
    这个时候再回顾之前为何执行两次onreadystatechange, 因为当state每次变化的时候都会执行到onreadystatechange,其实是readyState每次变化都会有执行onreadystatechange,因为我判断了this.status == 200 ,所以当服务器响应了之后返回了200的状态码,才会执行console.log(),才有上面的执行两次的问题。
    至此问题解决!!!

    总结
    以上为个人经验,希望能给大家一个参考,也希望大家多多支持知鸟论坛
  • 回复

    使用道具 举报

    发表于 2023-6-28 21:20:18 | 显示全部楼层
    惜颜705 2023-6-28 21:20:18 看全部
    我看不错噢 谢谢楼主!知鸟论坛越来越好!
    回复

    使用道具 举报

    发表于 2023-6-29 14:36:36 | 显示全部楼层
    心随674 2023-6-29 14:36:36 看全部
    楼主,我太崇拜你了!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-29 22:53:54 | 显示全部楼层
    风来时狂放 2023-6-29 22:53:54 看全部
    楼主太厉害了!楼主,I*老*虎*U!我觉得知鸟论坛真是个好地方!
    回复

    使用道具 举报

    发表于 2023-6-29 23:21:58 | 显示全部楼层
    dxf17 2023-6-29 23:21:58 看全部
    论坛不能没有像楼主这样的人才啊!我会一直支持知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-30 12:44:45 | 显示全部楼层
    小妖花满楼满fx 2023-6-30 12:44:45 看全部
    楼主,大恩不言谢了!知鸟论坛是最棒的!
    回复

    使用道具 举报

    发表于 2023-6-30 15:36:56 | 显示全部楼层
    123456868 2023-6-30 15:36:56 看全部
    楼主发贴辛苦了,谢谢楼主分享!我觉得知鸟论坛是注册对了!
    回复

    使用道具 举报

    发表于 2023-7-3 17:24:34 | 显示全部楼层
    向往草原403 2023-7-3 17:24:34 看全部
    这东西我收了!谢谢楼主!知鸟论坛真好!
    回复

    使用道具 举报

    发表于 2023-7-3 19:42:38 | 显示全部楼层
    123456865 2023-7-3 19:42:38 看全部
    这个帖子不回对不起自己!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-7-4 10:23:06 | 显示全部楼层
    123456823 2023-7-4 10:23:06 看全部
    楼主,我太崇拜你了!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    • 您可能感兴趣
    点击右侧快捷回复 【请勿灌水】
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则 返回列表

    RSS订阅| SiteMap| 小黑屋| 知鸟论坛
    联系邮箱E-mail:zniao@foxmail.com
    快速回复 返回顶部 返回列表