网络请求是前端开发中的核心概念,从XMLHttpRequest到Fetch API再到Ajax,这些术语确实需要系统了解。本文将用通俗易懂的语言解释这些概念,帮助你全面理解JavaScript中的网络请求。
网络请求是什么?为什么我们需要它?
想象一下,你在美团上点了一份外卖。你需要告诉商家你想要什么(请求),然后商家会给你回复(响应)。网页中的HTTP请求也是类似的过程!
简单来说,当你:
- 打开一个网页
- 点击"加载更多"按钮
- 提交一个表单
- 在网页上发送消息
这些操作背后,浏览器都在和服务器进行"对话",这就是HTTP请求的本质。
这种"对话"包括:
- 你说什么(请求方法:GET、POST等)
- 你对谁说(URL地址)
- 你怎么说(请求头)
- 说什么内容(请求体)
然后服务器会回应:
- 听到了没(状态码:200成功,404没找到等)
- 回应的方式(响应头)
- 回应的内容(响应体)
JavaScript中的两大网络请求主角
在JavaScript中,我们有两种主要的方式发送网络请求:
- XMLHttpRequest(简称XHR):老前辈,资历深但脾气有点怪
- Fetch API:新生代,时尚灵活但有时候太年轻气盛
我们先来看看这位老前辈。
XMLHttpRequest:老当益壮的网络请求大爷
XMLHttpRequest虽然名字里有"XML",但它其实什么数据都能处理。这就像一个叫"面条专家"的厨师,其实煲汤和炒菜也很拿手。
基本使用
// 创建一个XHR对象(相当于拿起电话准备打)
const xhr = new XMLHttpRequest();
// 设置请求(拨号)
xhr.open('GET', 'https://api.example.com/data', true); // true表示异步,就像你打电话后可以做别的事
// 设置接收数据的格式
xhr.responseType = 'json'; // 可以是'text'、'json'、'blob'等
// 监听状态变化(等待对方接电话并说话)
xhr.onreadystatechange = function() {
// readyState就像电话的状态:
// 0: 刚拿起电话
// 1: 开始拨号
// 2: 对方接听了
// 3: 对方正在说话
// 4: 通话结束
if (xhr.readyState === 4) { // 通话结束
if (xhr.status === 200) { // 对方好好回答了
console.log('收到数据啦:', xhr.response);
} else {
console.error('哎呀,出错了:', xhr.status);
}
}
};
// 更简单的方式监听(我只关心通话结束)
xhr.onload = function() {
if (xhr.status === 200) {
console.log('收到数据啦:', xhr.response);
} else {
console.error('哎呀,出错了:', xhr.status);
}
};
// 处理出错情况(电话线路问题)
xhr.onerror = function() {
console.error('网络出问题了,可能是你的WiFi断了?');
};
// 发送请 求(按下拨号键)
xhr.send(); // GET请求是空的,POST会带上数据
老实说,XHR的代码看起来有点复杂,这也是为什么后来大家都更喜欢用Fetch API或Axios。
发送POST请求
如果GET请求是"问问题",那POST请求就是"告诉对方一些信息":
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/users', true);
// 设置请求头(相当于告诉对方我们说的是什么语言)
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status === 201) { // 201表示"我已经创建了你要的东西"
console.log('用户创建成功啦:', xhr.response);
} else {
console.error('创建失败了,可能是表单填错了?', xhr.status);
}
};
// 准备要发送的数据
const data = {
name: '张三',
email: 'zhangsan@example.com'
};
// 发送数据(一定要先转成JSON字符串!)
xhr.send(JSON.stringify(data));
我第一次用POST请求时,就忘了把对象转成JSON字符串,调试了半天才发现问题。这是很多新手都会踩的坑!
上传文件
上传文件时,我们需要用到FormData对象:
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/upload', true);
// 监控上传进度(这是XHR的一个很酷的特性!)
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
const percentComplete = (e.loaded / e.total) * 100;
console.log('已经上传了:', percentComplete.toFixed(2) + '%');
// 这里可以更新进度条UI
}
};
xhr.onload = function() {
if (xhr.status === 200) {
console.log('文件上传成功!', xhr.response);
} else {
console.error('上传失败了,文件太大了?', xhr.status);
}
};
// 创建FormData对象(相当于一个虚拟表单)
const formData = new FormData();
// 假设页面上有个文件选择器
const fileInput = document.getElementById('fileInput');
formData.append('file', fileInput.files[0]);
formData.append('username', '张三'); // 可以添加额外信息
// 发送FormData
xhr.send(formData);
我记得有一次做文件上传功能,用户反馈上传大文件时没有进度提示,体验很差。加上这个进度监控后,用户满意度立刻提高了!