当前位置: 首页 > news >正文

原生 AJAX 揭秘:如何使用 XHR 发起请求

🚀 原生 AJAX 揭秘:如何使用 XHR 发起请求

🤔 什么是 XHR?

XMLHttpRequest是浏览器提供的一个内置对象,允许我们在后台与服务器交换数据。这意味着我们可以在不重新加载整个页面的情况下,更新网页的一部分。这就是著名的AJAX(Asynchronous JavaScript and XML) 技术的核心。

通俗比喻
如果把浏览器比作一家餐厅:

  • 传统页面刷新:你点完菜,必须离开餐厅,等厨房做好后,再重新进门坐下吃(整个页面重载)。
  • XHR (AJAX):你坐在座位上,派服务员(XHR 对象)去厨房催菜或加菜。菜做好了,服务员直接端到你桌上(局部更新),你不需要离开座位。

📂 目录

  1. 🛠️ 发起请求的标准五步法
  2. 💻 代码实战:GET 与 POST
  3. 📊 核心概念:readyState状态详解
  4. ⚠️ 常见陷阱与最佳实践
  5. 🔄 XHR vs Fetch:该选哪个?
  6. 💡 总结

1. 🛠️ 发起请求的标准五步法

使用 XHR 发起一个请求,通常遵循以下五个标准步骤。你可以把它当作一个模板来记忆。

第一步:创建对象

constxhr=newXMLHttpRequest();

第二步:配置请求

使用open()方法初始化请求。

// open(method, url, async)xhr.open('GET','https://api.example.com/data',true);
  • method: 请求类型 (GET,POST,PUT等)。
  • url: 请求地址。
  • async: 是否异步(默认为true强烈建议保持异步,否则会阻塞页面)。

第三步:设置回调(监听状态变化)

在发送之前,先告诉 XHR:“当状态改变时,该做什么”。

xhr.onreadystatechange=function(){// 处理逻辑写在这里};

第四步:发送请求

xhr.send();// GET 请求通常传 null 或不传// xhr.send(data); // POST 请求传入数据

第五步:处理响应

在回调函数中,检查状态码并获取数据。


2. 💻 代码实战:GET 与 POST

场景一:发起 GET 请求

constxhr=newXMLHttpRequest();// 1. 配置xhr.open('GET','https://jsonplaceholder.typicode.com/todos/1',true);// 2. 监听状态xhr.onreadystatechange=function(){// readyState === 4 表示请求完成// status === 200 表示 HTTP 成功if(xhr.readyState===4&&xhr.status===200){console.log('请求成功!');console.log(JSON.parse(xhr.responseText));// 解析 JSON 数据}elseif(xhr.readyState===4){console.error('请求失败,状态码:',xhr.status);}};// 3. 发送xhr.send();

场景二:发起 POST 请求(提交表单数据)

POST 请求通常需要设置请求头,并发送数据体。

constxhr=newXMLHttpRequest();// 1. 配置xhr.open('POST','https://jsonplaceholder.typicode.com/posts',true);// 2. 设置请求头(告诉服务器发送的是 JSON 格式)xhr.setRequestHeader('Content-Type','application/json;charset=UTF-8');// 3. 监听状态xhr.onreadystatechange=function(){if(xhr.readyState===4&&xhr.status===201){// 201 Createdconsole.log('创建成功!');console.log(JSON.parse(xhr.responseText));}};// 4. 发送数据constdata=JSON.stringify({title:'Foo',body:'Bar',userId:1});xhr.send(data);

3. 📊 核心概念:readyState状态详解

xhr.readyState是一个整数,表示请求当前的阶段。理解它是处理异步逻辑的关键。

状态常量含义说明
0UNSENT未初始化对象已创建,但未调用open()
1OPENED已打开已调用open(),但未调用send()
2HEADERS_RECEIVED头已接收已调用send(),且已接收到响应头
3LOADING加载中响应体正在下载中(responseText已有部分数据)
4DONE完成整个请求过程结束,数据接收完毕

重点
我们最关心的是readyState === 4。只有在这个状态下,xhr.responseText才是完整可用的。


4. ⚠️ 常见陷阱与最佳实践

❌ 陷阱 1:忘记检查 status

只判断readyState === 4是不够的。如果服务器返回 404 或 500,readyState也是 4,但请求实际上是失败的。

// ✅ 正确写法if(xhr.readyState===4){if(xhr.status>=200&&xhr.status<300){// 成功处理}else{// 错误处理}}

❌ 陷阱 2:回调地狱与代码冗余

如果有多个请求依赖,XHR 的嵌套回调会让代码难以维护(Callback Hell)。

✅ 最佳实践
在现代开发中,如果必须用原生 JS,建议将 XHR封装成 Promise,或者直接使用fetch

// 封装成 Promise 的简单示例functionrequest(url){returnnewPromise((resolve,reject)=>{constxhr=newXMLHttpRequest();xhr.open('GET',url);xhr.onload=()=>{if(xhr.status===200)resolve(JSON.parse(xhr.responseText));elsereject(newError(xhr.statusText));};xhr.onerror=()=>reject(newError('Network Error'));xhr.send();});}// 使用 async/await 调用,代码更清晰asyncfunctiongetData(){try{constdata=awaitrequest('https://api.example.com/data');console.log(data);}catch(error){console.error(error);}}

❌ 陷阱 3:跨域问题 (CORS)

XHR 同样受浏览器的同源策略限制。如果请求跨域接口,后端必须配置正确的 CORS 头(如Access-Control-Allow-Origin),否则前端会报错。


5. 🔄 XHR vs Fetch:该选哪个?

特性XMLHttpRequest(XHR)fetchAPI
出现时间古老 (IE5 时代)现代 (ES6+)
语法风格基于事件回调基于Promise
代码简洁度较繁琐简洁优雅
错误处理需手动检查 status网络错误才 reject,HTTP 错误需手动检查
进度监控✅ 原生支持 (onprogress)❌ 需借助 ReadableStream (较复杂)
兼容性✅ 极好 (包括 IE)❌ IE 不支持 (需 polyfill)

建议

  • 新项目:首选fetchaxios
  • 需要上传进度条:XHR 依然有优势,或者使用axios(底层基于 XHR)。
  • 维护老项目/兼容 IE:必须掌握 XHR。

💡 总结

步骤关键代码作用
1. 创建new XMLHttpRequest()实例化对象
2. 配置xhr.open('GET', url)设定方法和地址
3. 监听xhr.onreadystatechange绑定状态变化回调
4. 发送xhr.send(body)发出请求
5. 判断readyState === 4 && status === 200确认成功并处理数据

🚀 博主寄语
虽然fetch是未来,但XHR是过去和现在的桥梁。
理解 XHR 的工作原理,能让你更深入地理解 HTTP 请求的生命周期、异步编程模型以及浏览器的网络机制。

记住口诀
新建对象 Open 配,
监听状态别嫌累。
Send 发送等回应,
四二零零才到位。

希望这篇文档能帮你彻底搞懂 XHR 请求!如果有疑问,欢迎在评论区留言。👇

喜欢这篇文章吗?记得点赞、收藏、转发哦!❤️

http://www.jsqmd.com/news/791766/

相关文章:

  • SpringBoot + Tomcat部署,你的文件上传接口有‘定时炸弹’吗?聊聊/tmp目录清理那点事
  • 2026年4月型钢批发厂家推荐,道轨槽钢/低温方管/异型钢/Q345D方矩管/门架型钢/低合金方管,型钢加工厂有哪些 - 品牌推荐师
  • Gerrit Commit批量获取
  • 那个视频去水印下载软件好用?视频去水印有啥免费好用的软件? 靠谱方法分享 - 爱上科技热点
  • 泰州汽车贴膜价格透明无隐形消费的店 - 速递信息
  • Halcon实战:巧用smallest_rectangle2()精准定位与测量不规则目标
  • 终极指南:用Python实现微信自动化,告别重复操作!
  • 从Vivado到VCS/Verdi:IC新人的Linux环境效率跃迁手记(含一键仿真脚本)
  • Agent 应用时代将至,传统基础设施面临挑战,openYuanrong 等系统或成破局关键
  • 从千万QPS到零误触发:奇点智能大会首曝动态权重灰度算法与实时置信度熔断机制
  • 从Pizza.owl案例出发:手把手拆解Protege本体构建核心三要素
  • 深入理解 JavaScript:什么是可迭代对象 (Iterable)?
  • 在RK3399上跑通ORB-SLAM2和VINS-MONO,我踩过的那些坑(含RealSense D435i兼容性测试)
  • 告别手动开关!用ESP8266+Arduino IDE实现高精度定时控制(实测误差<1秒)
  • TikTok评论采集全攻略:零代码批量获取用户反馈的终极方案
  • 如何3分钟掌握终极树状书签管理神器:Neat Bookmarks完全指南
  • Windows Defender完全掌控指南:3分钟彻底禁用Windows Defender的终极解决方案
  • 抖音批量下载工具架构解析:从技术实现到实战配置指南
  • KMS智能激活工具终极指南:一键解决Windows和Office激活难题
  • 别再傻傻分不清!同步复位、异步复位、Byte Enable,一个HDLbits实验搞定所有D触发器变种
  • 从光衰减到泥沙传输:深入拆解FVCOM-FABM-ERSEM耦合中的关键物理过程
  • 企业内如何利用Taotoken实现API Key的精细化权限管理与审计
  • 老旧S7-200/300如何低成本联网?实测第三方通讯桥接器在IFIX项目中的应用
  • 大模型治理不是加监控,而是重定义SLI:奇点智能大会联合信通院发布的《大模型服务治理黄金标准V1.2》正式版,仅开放下载72小时(附11个生产环境故障复盘案例)
  • 镜像视界(浙江)科技有限公司 —— 数字孪生与视频孪生领域的深度引领者
  • 如何用AI算法征服2048游戏?完整教程带你从新手到高手
  • 当你的客户想运行自己的工作流,你该怎么办
  • 从JPG到GeoTIFF:一次搞懂JGW文件、仿射变换与栅格数据的地理配准核心原理
  • 从‘//’到‘///’:解锁C#注释的正确姿势与隐藏的IDE效率技巧
  • FreeRouting终极指南:如何快速掌握开源PCB自动布线工具