第37篇:原生AJAX从零手写源码——彻底弄懂前端网络请求底层
前言
在前面章节我们使用过 Fetch、封装过 Promise 请求。
但Fetch 是现代API,真正前端网络底层根基永远是:AJAX(XMLHttpRequest)。
绝大多数新人只会调用接口,从来不知道:
网络请求底层是怎么建立的
请求头、响应头如何配置
请求状态码、 readyState 到底是什么
为什么可以异步不阻塞页面
本篇带你从零手写完整原生AJAX源码,弄懂前端网络底层,吊打面试网络原理题,同时为下一篇跨域知识点打下绝对基础。
一、AJAX是什么?(面试满分定义)
AJAX 是异步的 JavaScript 和 XML,核心作用:在不刷新页面的情况下,与服务器进行异步数据通信。
前端所有接口请求底层根源都是 AJAX:
jQuery.ajax 底层 => XMLHttpRequest
axios 底层 => XMLHttpRequest
Fetch 是新规范,但底层思想依然是AJAX异步通信
二、AJAX 核心五大步骤(必背)
创建请求实例:new XMLHttpRequest()
初始化请求:open(请求方式, 接口地址, 是否异步)
监听状态变化:onreadystatechange
发送请求:send()
接收响应数据:判断状态码、解析数据
三、readyState 五状态详解(面试必考)
0:未初始化,未调用open
1:请求已建立,未发送
2:请求已发送,响应头已返回
3:正在接收响应数据(部分返回)
4:请求彻底完成,数据全部接收成功
我们真正处理业务逻辑,只判断readyState === 4
四、状态码 status 含义
200:请求成功
404:接口地址不存在
403:权限不足
500:服务器报错
五、手写完整AJAX(GET请求完整版)
// 1. 创建xhr实例 const xhr = new XMLHttpRequest(); // 2. 初始化请求方式和地址 // 第三个参数:true=异步 false=同步 xhr.open("GET","https://jsonplaceholder.typicode.com/posts/1",true); // 3. 监听状态变化 xhr.onreadystatechange = function(){ // 请求完成 if(xhr.readyState === 4){ // 请求成功 if(xhr.status === 200){ // 拿到服务器返回数据 console.log("请求成功:",JSON.parse(xhr.responseText)); }else{ console.log("请求失败:",xhr.status); } } } // 4. 发送请求 xhr.send(null);
六、手写POST请求(带请求体、请求头)
const xhr = new XMLHttpRequest(); xhr.open("POST","https://xxx.com/api",true); // POST必须手动设置请求头 xhr.setRequestHeader("Content-Type","application/json"); xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ console.log(xhr.status,xhr.responseText); } } // 传递JSON参数 const data = JSON.stringify({name:"张三",age:18}); xhr.send(data);
七、封装Promise版AJAX(企业通用)
把原生AJAX封装成 Promise,兼容 async/await,对标 axios 底层思想。
function ajax(url,method="GET",data=null){ return new Promise((resolve,reject)=>{ const xhr = new XMLHttpRequest(); xhr.open(method,url,true); // 设置请求头 xhr.setRequestHeader("Content-Type","application/json"); xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ if(xhr.status >=200 && xhr.status <300){ resolve(JSON.parse(xhr.responseText)); }else{ reject("请求失败:" + xhr.status); } } } // 发送数据 xhr.send(data ? JSON.stringify(data) : null); }) } // 使用 ajax("https://jsonplaceholder.typicode.com/posts") .then(res=>console.log(res)) .catch(err=>console.log(err));
八、本篇结语
学完本篇,你不再是只会调用 Fetch、axios 的小白。
你真正掌握了前端网络请求底层原理,理解请求全过程、状态流转、头部配置、参数传递。
所有网络框架万变不离其宗,底层全部是 AJAX。
下一篇我们攻克前端超级高频痛点:跨域问题与全套解决方案,彻底解决项目接口报错问题。
