JavaScript 发起网络请求
fetch
fetch 是现代浏览器中用于发起网络请求的 API,它提供了一种更加简洁和强大的方式来获取资源(例如从网络加载数据)。与传统的 XMLHttpRequest 相比,fetch 提供了更简洁的语法和更强的功能,并且返回的是 Promise,使得异步编程更加易于理解和处理。
fetch 允许我们通过 HTTP 请求(如 GET、POST、PUT、DELETE 等方法)向服务器请求数据,并异步地处理请求结果。它是异步的,意味着不会阻塞其他 JavaScript 代码的执行。
语法:
fetch(url, options)
.then(response => response.json()) // 将响应体解析为 JSON
.then(data => console.log(data)) // 处理返回的数据
.catch(error => console.error('Error:', error)); // 错误处理
参数说明:
- url: 请求的目标 URL(可以是相对路径或绝对路径)。
- options: 可选的配置对象,包含请求方法、头信息、请求体等。
options 常用选项:
method:请求方式,默认为 GET。常见值有 POST、PUT、DELETE、PATCH 等。
示例:
fetch('https://example.com', {method: 'POST', });
headers:请求头,通常是一个对象,包含键值对。
示例:
fetch('https://example.com', {headers: {'Content-Type': 'application/json','Authorization': 'Bearer token',} });
body:请求体,仅在方法是 POST、PUT 等时使用,通常是 JSON 格式的数据。
示例:
fetch('https://example.com', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ name: 'John', age: 30 }) });
mode:控制请求的跨域行为,常用的值有 no-cors、cors 和 same-origin。默认为 cors。
- no-cors:不携带跨域凭证,限制请求返回内容的访问。
- cors:允许跨域请求,需目标服务器支持 CORS。
- same-origin:仅允许同源请求(即相同的协议、域名和端口)。
示例:
fetch('https://example.com', {mode: 'no-cors', // 不发送跨域请求 });
cache:控制缓存行为,常用值有 default、no-store、reload 等。
- default:按常规缓存机制处理,有缓存就用缓存,没有缓存就从网络加载。
- no-store:不缓存,始终从网络加载。
- reload:强制重新加载,不使用缓存(一点缓存不能用,确保从网络加载最新数据)。
- no-cache:查找缓存并验证(缓存可用返回304 状态码),缓存不可用重新从网络加载。
- force-cache:强制使用缓存,如果没有则从网络加载。
- only-if-cached:只使用缓存,缓存没有则不请求。
示例:
fetch('https://example.com', {cache: 'no-cache', // 禁用缓存 });
credentials:控制是否发送 cookies、http认证信息等,常见值有 same-origin 和 include。
- same-origin:仅在同源请求时自动携带凭证(默认)。
- include:无论同源还是跨域请求,都携带凭证。
- omit:请求不携带凭证,适用于公开资源或不需要身份验证的请求。
示例:
fetch('https://example.com', {credentials: 'include' });
发送 GET 请求
示例:
fetch('http://127.0.0.1:8080/test?name=123').then(response => response.json()) // 解析 JSON 响应,// 这个 response.json() 不是返回的数据,还要调用 response.json() 函数,等待处理完成返回给下一个 then 才是处理好的数据.then(data => {console.log(data); // 输出后台返回的数据}).catch(error => console.error('Error:', error)); // 错误处理
发送 POST 请求
示例: 请求头:Content-Type: application/x-www-form-urlencoded
const data = {name: 'Tom'
};
// 将对象转换为 x-www-form-urlencoded 格式
const urlEncodedData = new URLSearchParams(data).toString();fetch('http://127.0.0.1:8080/test', {method: 'POST',headers: {'Content-Type': 'application/x-www-form-urlencoded',},body: urlEncodedData,
}).then(response => response.json()) // 解析 JSON 响应 // 这个 response.json() 不是返回的数据,还要调用 response.json() 函数,等待处理完成返回给下一个 then 才是处理好的数据.then(data => {console.log(data); // 输出后台返回的数据}).catch(error => console.error('Error:', error)); // 错误处理
示例: 请求头:Content-Type: application/json
fetch('http://127.0.0.1:8080/test', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({name: 'Tom'}),
}).then(response => response.json()) // 解析 JSON 响应 // 这个 response.json() 不是返回的数据,还要调用 response.json() 函数,等待处理完成返回给下一个 then 才是处理好的数据.then(data => {console.log(data); // 输出后台返回的数据}).catch(error => console.error('Error:', error)); // 错误处理
处理后台异常响应
fetch 只会在网络失败或请求被阻止时拒绝 Promise。对于 4xx 或 5xx 错误(如 404 或 500),它依然会返回一个 fulfilled (已完成)状态的 Promise,所以需要手动检查 response.ok 来判断请求是否成功。
示例:
fetch('http://127.0.0.1:8080/test?name=123').then(response => {// 处理后台程序异常的返回,例如 500if (!response.ok) {throw new Error('Network response was not ok');}return response.json();}).then(data => {console.log(data); }).catch(error => console.error('Error:', error));
async / await
async / await 是 JavaScript 中用来处理异步操作的一种语法糖,它基于 Promise,使得处理异步代码变得更加简洁和易读。async/await 主要是为了替代 .then() 的链式调用,目的是让异步代码更加简洁和可读。虽然 fetch 本身是异步的,使用 async/await 使得你可以像写同步代码一样处理异步操作,从而避免了嵌套 .then() 造成的“回调地狱”(callback hell)问题。
async
async 是一个用于声明异步函数的关键字。它告诉 JavaScript 引擎,这个函数是异步的,返回的结果会是一个 Promise 对象。
当你声明一个 async 函数时,无论函数内部是否有 return,它都会自动返回一个 Promise。如果你在函数内部返回一个值,Promise 会自动将该值包装起来。
语法:
async function foo() {// 异步操作
}
console.log(foo()); // 打印 Promise { undefined },表示是一个Promise对象
示例:
// 定义一个 async 函数
async function foo() {return "Hello World";
}// 调用 async 函数,调用 then 函数处理 async 返回结果。
foo().then((result) => {console.log(result);
});
await
await 用于等待一个 Promise 对象的结果,它只能在 async 函数内部使用。当遇到 await 时,JavaScript 会暂停 async 函数的执行,等待 Promise 被解析(resolved)或拒绝(rejected)后再继续执行。
没有 await 时: async 函数返回一个 Promise,你需要使用 .then() 或 .catch() 来处理这个 Promise 的结果。
有 await 时: await 会暂停 async 函数的执行,直到 async 函数的返回结果 Promise 被解析,并返回解析的结果。你可以直接在 async 函数内部处理异步结果,而不需要在 async 函数外部使用 .then() 来处理结果了。
示例对比: // 没用 await 时
async function foo() {return "Hello, World!";
}// 没有 await 时,这样处理 async 的返回结果
foo().then(result => {console.log(result); // 输出: "Hello, World!"
});
示例对比: // 使用 await 时
async function foo() {// 有 await 时,直接在这里等待 async 函数的返回结果,然后在 async 函数内部就把返回结果处理了。const result = await "Hello, World!";console.log(result); // 输出: "Hello, World!"
}foo();
发送 GET 请求
示例:
// 创建一个 async 函数
async function get() {// 使用 await fetch 发送 GET 请求const response = await fetch('http://127.0.0.1:8080/test?name=123');// 判断请求后台是否异常if (!response.ok) {throw new Error('请求失败,状态码:' + response.status);}const data = await response.json(); // 解析 JSON 响应体console.log(data); // 输出后台返回的数据
}// 调用 async 函数
get().catch(error => console.error('Error:', error));
发送 POST 请求
示例: 请求头:Content-Type: application/x-www-form-urlencoded