网站
引入
网页需要和服务器交换数据:获取用户信息、提交表单、加载列表等。
JS 提供了两种发送网络请求的方式:早期的 XMLHttpRequest 和现代的 fetch()。
正文
定义
定义
网络请求是 JS 向服务器发送 HTTP 请求,获取数据或提交数据的过程。常用
XMLHttpRequest(旧)和fetch()(新)两种方式。
HTTP 请求方法
| 方法 | 用途 | 特点 |
|---|---|---|
GET | 获取数据 | 参数拼在 URL 上 |
POST | 提交数据 | 参数放在请求体中 |
PUT | 更新数据(全量) | 替换整个资源 |
DELETE | 删除数据 | 删除指定资源 |
PATCH | 更新数据(部分) | 只更新部分字段 |
最常用的是 GET 和 POST。
fetch() 基础用法
fetch() 是现代浏览器推荐的请求方式。
GET 请求
fetch("https://api.example.com/users")
.then(function (response) {
return response.json();
})
.then(function (data) {
console.log(data);
});默认就是 GET 请求,只需要传入 URL 即可。
POST 请求
fetch("https://api.example.com/users", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: "张三",
age: 25
})
})
.then(function (response) {
return response.json();
})
.then(function (data) {
console.log(data);
});POST 请求需要配置 method、headers 和 body。
fetch() 的第二个参数
| 配置项 | 作用 | 示例 |
|---|---|---|
method | 请求方法 | "GET"、"POST" |
headers | 请求头 | { "Content-Type": "application/json" } |
body | 请求体 | JSON.stringify(data) |
响应处理
fetch() 返回一个 Promise,.then() 里拿到的 response 对象不是最终数据,需要进一步解析。
| 方法 | 作用 |
|---|---|
response.json() | 解析为 JSON 对象 |
response.text() | 解析为纯文本 |
response.blob() | 解析为二进制数据(文件、图片) |
response.status | HTTP 状态码 |
response.ok | 状态码是否在 200-299 范围 |
response.headers | 响应头 |
fetch("https://api.example.com/users")
.then(function (response) {
console.log("状态码:" + response.status);
return response.json();
})
.then(function (data) {
console.log("数据:", data);
});错误处理
fetch() 只有在网络故障时才会触发 .catch(),HTTP 错误(404、500)不会自动报错。
fetch("https://api.example.com/users")
.then(function (response) {
if (!response.ok) {
throw new Error("HTTP 错误:" + response.status);
}
return response.json();
})
.then(function (data) {
console.log(data);
})
.catch(function (error) {
console.log("请求失败:" + error.message);
});带查询参数的 GET 请求
const keyword = "js";
const page = 1;
fetch("https://api.example.com/search?q=" + keyword + "&page=" + page)
.then(function (response) {
return response.json();
})
.then(function (data) {
console.log(data);
});也可以用 URLSearchParams 来构建查询参数:
const params = new URLSearchParams({
q: "js",
page: 1
});
fetch("https://api.example.com/search?" + params)
.then(function (response) {
return response.json();
})
.then(function (data) {
console.log(data);
});XMLHttpRequest 基础用法
XMLHttpRequest(简称 XHR)是早期的请求方式,了解它有助于阅读旧代码。
GET 请求
const xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/users");
xhr.onload = function () {
if (xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
console.log(data);
}
};
xhr.onerror = function () {
console.log("请求失败");
};
xhr.send();POST 请求
const xhr = new XMLHttpRequest();
xhr.open("POST", "https://api.example.com/users");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = function () {
if (xhr.status === 200) {
const data = JSON.parse(xhr.responseText);
console.log(data);
}
};
xhr.send(JSON.stringify({
name: "张三",
age: 25
}));XHR 和 fetch 对比
| 对比 | XMLHttpRequest | fetch() |
|---|---|---|
| 写法 | 繁琐,回调多 | 简洁,基于 Promise |
| 错误处理 | onerror | .catch() |
| HTTP 错误 | status 判断 | 也需要手动判断 |
| 中止请求 | xhr.abort() | AbortController |
| 上传进度 | 支持 | 不支持 |
| 兼容性 | 所有浏览器 | IE 不支持 |
例子
加载并渲染列表
<button id="loadBtn">加载</button>
<ul id="list"></ul>
<p id="loading" style="display: none;">加载中...</p>const loadBtn = document.querySelector("#loadBtn");
const list = document.querySelector("#list");
const loading = document.querySelector("#loading");
loadBtn.addEventListener("click", function () {
loading.style.display = "block";
list.innerHTML = "";
fetch("https://api.example.com/items")
.then(function (response) {
if (!response.ok) {
throw new Error("加载失败");
}
return response.json();
})
.then(function (items) {
items.forEach(function (item) {
const li = document.createElement("li");
li.textContent = item.name;
list.appendChild(li);
});
})
.catch(function (error) {
console.log(error.message);
})
.finally(function () {
loading.style.display = "none";
});
});提交表单数据
<form id="form">
<input name="title" type="text" placeholder="标题">
<textarea name="content" placeholder="内容"></textarea>
<button type="submit">发布</button>
</form>const form = document.querySelector("#form");
form.addEventListener("submit", function (event) {
event.preventDefault();
const title = form.querySelector("[name='title']").value;
const content = form.querySelector("[name='content']").value;
if (title === "" || content === "") {
return;
}
fetch("https://api.example.com/posts", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ title: title, content: content })
})
.then(function (response) {
return response.json();
})
.then(function (data) {
console.log("发布成功:", data);
form.reset();
});
});form.reset() 会清空表单所有输入框的内容。
常见写法
| 写法 | 作用 |
|---|---|
fetch(url) | 发送 GET 请求 |
fetch(url, { method: "POST", body: … }) | 发送 POST 请求 |
response.json() | 解析 JSON 响应 |
response.text() | 解析纯文本响应 |
.then(fn).catch(fn) | 处理成功和错误 |
JSON.stringify(data) | 把对象转为 JSON 字符串 |
JSON.parse(text) | 把 JSON 字符串转为对象 |
特点
fetch()写法简洁,基于 Promise,是现代推荐的请求方式XMLHttpRequest是旧写法,但兼容性好,有些老项目还在用GET用于获取数据,参数在 URL 上POST用于提交数据,参数在请求体中response.json()解析 JSON 数据,response.text()解析纯文本- HTTP 错误状态码不会触发
.catch(),需要手动检查response.ok .finally()无论成功或失败都会执行,适合隐藏加载提示
注意事项
fetch()是异步的,不能直接用const data = fetch(url)获取数据- 跨域请求需要服务器配置 CORS
- POST 请求发送 JSON 数据时,必须设置
Content-Type: application/json JSON.stringify()把 JS 对象转成字符串,JSON.parse()把字符串转回对象- 请求可能需要一段时间,期间应该给用户展示”加载中”的提示
- 网络请求可能失败,一定要处理错误情况
理解
可以把网络请求理解成”寄信”。
发请求就是写信寄出去,服务器收到信后回复。
fetch() 是现代快递,流程简单,写好地址(URL)、内容(body),寄出去后等回复。
XMLHttpRequest 是传统邮局,步骤多,但效果一样。
我理解网络请求的重点是:用 fetch() 发请求,用 .then() 处理回复,用 .catch() 处理异常。
引出
掌握了网络请求的基础后,可以深入学习 JS Ajax,了解 Ajax 在实际项目中的应用场景。
网络请求是异步操作,理解 JS Promise 和 JS async await 可以让异步代码更容易读写。