Fetch API 是一个现代 JavaScript 接口,通过基于 Promise 的语法简化 HTTP 请求,使代码更加简洁易用。借助 Fetch API,您可以在无需重新加载整个页面的情况下从服务器请求数据,从而提升应用的速度和交互体验。您可以轻松发送 GET、POST、PUT 或 DELETE 请求,以与各种 API 进行交互。同时,Fetch API 还可简化各类数据和 HTTP 方法的处理流程。自定义请求标头和管理不同类型的内容变得非常简单,让您能够顺畅使用各种服务。
本文将介绍如何使用 Fetch API、它对 Web 应用的好处以及如何使用代理确保安全高效的数据处理。欢迎查看最佳代理提供商名单 ,了解 Bright Data 为何是最佳选择。
了解 Fetch API
Fetch API 可用于发送异步 HTTP 请求,具体而言,它会向服务器发送请求并返回 Promise,然后在获取到服务器的响应数据后对 Promise 进行解析。在 JavaScript 开发中,Fetch API 支持通过 HTTP 请求(例如 GET、POST、PUT)与服务器进行动态交互,让应用无需重新加载页面即能与服务器通信。以下是 Fetch API 的部分优点:
- 使用 Promise 简化语法:Fetch API 使用 Promise,消除了 XMLHttpRequest 的复杂操作,让您可以轻松编写更简洁、更易读的代码。
- 支持多种数据格式:您可以使用 JSON、文本和二进制大型对象 (blob) 等格式,这有助于轻松解析和处理不同类型的响应。
- 提供流和响应对象:您可以使用可读流检查和更改响应,并根据应用需求调整数据获取方式。
- 优化错误处理:默认情况下,Fetch 不会因 HTTP 错误状态码抛出错误,但它支持更明确的响应检查。
- 简化回调机制:您无需编写大量回调函数,只需使用
.then()
、.catch()
或async/await
即可了解请求何时完成。
您现已了解使用 Fetch API 的优点,接下来我们将深入探讨它的主要特性和功能。
异步操作
Fetch API 采用异步机制,在获取到服务器响应后解析 Promise。这种方式不会造成 UI 的阻塞,能够为用户提供流畅的体验。让我们来看一些示例。
GET 请求
以下示例展示了如何使用 Fetch API 发送 GET 请求:
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log('Data fetched:', data);
})
.catch((error) => {
console.error('Fetch error:', error);
});
这段代码展示了如何使用 Fetch API 从 jsonplaceholder.typicode.com
获取帖子数据。它通过 response.ok
检查响应是否正常,如果不正常,则抛出错误。然后,它使用 response.json()
将响应解析为 JSON 格式。所有错误(无论是网络问题、响应格式错误还是解析失败)均在 .catch()
代码块中处理。
POST 请求
以下示例展示了如何使用 Fetch API 发送 POST 请求:
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-type': 'application/json; charset=UTF-8',
},
body: JSON.stringify({
title: 'New Post',
body: 'Hello World! This is a test.',
userId: 1,
}),
})
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log('New Post created:', data);
})
.catch((error) => {
console.error('Fetch error:', error);
});
这段代码展示了如何通过 Fetch API 使用 POST 方法发送请求来创建新资源。POST 请求与 GET 请求类似,但该类请求中包含标头,用来告知服务器:API 正在发送 JSON 数据。实际的 JSON 数据位于 body 字段中。
与 API 集成
您可以使用 Fetch API 向公共或私有 API 发送请求,例如获取图表、控制面板或其他基于数据的功能所需的数据。它使用基于 Promise 的流程,允许 Web 应用与外部服务进行通信,处理请求和响应。
下方是一个基本示例,展示了如何通过 OpenWeatherMap API 获取天气数据:
const city = "London,uk";
const apiKey = "YOUR_API_KEY";
const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&APPID=${apiKey}`;
fetch(url)
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then((weatherData) => {
console.log("Weather data for London:", weatherData);
})
.catch((error) => {
console.error("Error fetching weather data:", error);
});
将
YOUR_API_KEY
替换为实际 API 密钥。
这段代码使用 OpenWeather 的 API 获取伦敦的天气数据。weatherData
对象包含温度、湿度和天气状况等详细信息,可以直接集成到您的 UI 中。
在终端或 shell 中运行这段代码(使用 node filename.js
命令),应该会看到如下输出:
Weather data for London: {
coord: { lon: -0.1257, lat: 51.5085 },
weather: [
{
id: 804,
main: 'Clouds',
description: 'overcast clouds',
icon: '04d'
}
],
base: 'stations',
main: {
temp: 273.42,
feels_like: 273.42,
temp_min: 272.59,
temp_max: 274.87,
pressure: 1021,
humidity: 87,
sea_level: 1021,
grnd_level: 1016
},
visibility: 10000,
wind: { speed: 0.51, deg: 0 },
clouds: { all: 99 },
dt: 1736525048,
sys: {
type: 2,
id: 268730,
country: 'GB',
sunrise: 1736496173,
sunset: 1736525567
},
timezone: 0,
id: 2643743,
name: 'London',
cod: 200
}
应用经常需要与外部 API 交互来获取外部数据。因此,使用清晰统一的方式来集成外部服务是构建可扩展 Web 应用的关键。
错误处理
与需要设置多个事件处理程序来管理网络错误的旧式 AJAX 方法(如 XMLHttpRequest)相比,Fetch 使用 Promise 和单个 .catch()
代码块,大大简化了错误处理流程。Fetch 只会在出现网络错误(例如无网络连接)时才会拒绝 Promise,不会因为 404
或 500
等 HTTP 错误码而抛出错误。要判断是否发生了这些错误,必须手动检查 response.ok
。如果 response.ok
为 false
,则表示服务器返回的状态码不在 200-299 范围内。以下示例展示了 Fetch 如何处理因无效端点导致请求失败时的错误:
fetch('https://jsonplaceholder.typicode.com/invalid-endpoint')
.then((response) => {
if (!response.ok) {
throw new Error(`Failed to fetch. Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log('This will not run if response is not ok');
})
.catch((error) => {
console.error('Network or response error:', error.message);
});
运行这段代码时,您会收到输出消息:网络或响应错误:获取失败。状态码:404
。由于端点不存在,代码会在检查 !response.ok
后抛出错误。
将代理与 Fetch API 结合使用
代理可以通过提供额外的安全性、可扩展性和地理定位功能来增强 Fetch API 功能。代理充当客户端和互联网之间的中介,提供唯一的 IP 地址、额外的安全层以及更灵活的资源获取方法。将代理与 Fetch 结合使用,可以在数据提取或网页抓取活动中提供匿名保护,防止 IP 地址遭到封禁。使用代理还具有如下优势:
- 增强安全性:代理可以隐藏 IP 地址,降低 IP 遭受恶意攻击的风险。
- 可扩展性:代理可以将请求分布到多个 IP,防止达到速率限制或遭到封禁。
- 地理位置灵活性:代理可用于从不同位置发送 HTTP 请求,这对访问仅限特定地区的内容很有帮助。
代理类型
代理分为不同的类型,每类代理都有其特定的应用场景。代理分类如下:
- 住宅代理:这类代理使用来自真实住宅地址的 IP,受到网站的高度信任,虽然价格较高,但在目标网站封禁数据中心 IP 的流量时效果更好。
- 轮换代理:这类代理会在每次请求或会话时自动轮换 IP 地址,特别适合大规模数据提取,可以有效降低触及服务器限制或被列入黑名单的风险。
- 数据中心代理:这类代理来自数据中心,成本较低且速度较快,但频繁使用可能会遭到封禁。
将 Bright Data 代理与 Fetch API 集成
Bright Data 提供高级代理服务,可与基于 Fetch 的应用集成。这些代理服务不仅提供住宅和数据中心代理的选择,根据企业级项目的需求扩展数据获取功能,还能通过自动 IP 轮换实现高效可靠的数据收集。
以下示例展示了如何将 Bright Data 代理与 Fetch API 集成:
import fetch from "node-fetch";
import { HttpsProxyAgent } from "https-proxy-agent";
const proxyHost = "BRIGHT_DATA_PROXY_HOST:PORT";
const proxyUsername = "BRIGHT_DATA_USERNAME";
const proxyPassword = "BRIGHT_DATA_PASSWORD";
const proxyUrl = `http://${proxyUsername}:${proxyPassword}@${proxyHost}`;
const targetUrl = "https://jsonplaceholder.typicode.com/posts";
// Create a proxy agent
const agent = new HttpsProxyAgent(proxyUrl);
fetch(targetUrl, { agent })
.then((response) => {
if (!response.ok) {
throw new Error(`Error fetching data. Status: ${response.status}`);
}
return response.json();
})
.then((data) => {
console.log("Data fetched via proxy:", data);
})
.catch((error) => {
console.error("Proxy fetch error:", error);
});
这段代码展示了如何使用 fetch
和 HttpsProxyAgent
通过特定代理发送请求,接着定义了代理的详细信息并创建了代理助手,然后还演示了如何通过 fetch
使用该代理从目标 URL 获取数据。
要配置代理,必须使用
node-fetch
提供的Fetch API
。有关更多信息,请查看 node-fetch 文档。具体代码会随着所选代理类型的不同而变化。请查阅 Bright Data 官方文档,了解最新信息。
Fetch API 最佳实践
在使用 Fetch API 发送请求时,为提升效率和性能,请遵循以下最佳实践:
响应缓存
为了减轻服务器负载并提升整体用户体验,您可以使用缓存机制存储经常请求的数据,从而避免重复的服务器调用。以下示例展示了如何在发送网络请求前检查数据是否已缓存:
const cache = new Map();
async function fetchWithCache(url) {
if (cache.has(url)) {
console.log("Fetching from cache:", url);
return cache.get(url);
}
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
cache.set(url, data);
console.log("Fetched and cached:", url);
return data;
} catch (error) {
console.error("Fetch error:", error);
throw error;
}
}
fetchWithCache("https://jsonplaceholder.typicode.com/posts")
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));
避免重复请求已缓存的数据有助于提高性能并缩短加载时间。
超时处理
设置超时可以防止 Fetch 请求无限期挂起。您可以使用 AbortController
取消超过指定时长的请求。在下方示例中,超时设置为 3 秒,而默认超时值是 5 秒:
async function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => {
console.warn("Fetch request timed out:", url);
controller.abort();
}, timeout);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("Fetch timeout or error:", error);
throw error;
}
}
fetchWithTimeout("https://jsonplaceholder.typicode.com/posts", 3000)
.then((data) => console.log(data))
.catch((error) => console.error("Error:", error));
这样可以确保超出指定超时时间的请求被及时中止,并妥善处理其他错误。
请求限流
为了防止 API 因请求太多而过载,您应该实施限流来控制请求的频率。因此,您应该限制在特定时间范围内可以发出的请求数量。以下示例展示了如何创建限流
函数,确保函数在指定间隔(限制
)内最多执行一次:
function throttle(func, limit) {
let lastFunc;
let lastRan;
return function (...args) {
const context = this;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function () {
if (Date.now() - lastRan >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
const throttledFetch = throttle(async (url) => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log("Throttled fetch data:", data);
} catch (error) {
console.error("Throttled fetch error:", error);
}
}, 2000);
throttledFetch("https://jsonplaceholder.typicode.com/posts");
console.log("Fetching again in 2 seconds...");
throttledFetch("https://jsonplaceholder.typicode.com/posts");
throttledFetch
函数使用限流
工具来控制 API 请求,确保从 URL 获取数据的重复调用之间至少间隔 2 秒。这种方式可以防止重复或过度调用 API,同时能够处理错误并记录获取的数据。
结语
Fetch API 简化了现代 Web 应用中的异步操作和数据处理。然而,在处理大规模或地理定位请求时,可能会遇到 IP 封禁、请求限速和验证码等问题。
Bright Data 的 Scraper API 和抓取浏览器能够有效解决这些问题。Scraper API 可绕过反抓取措施,实现无缝数据提取,而抓取浏览器则可高效处理 JavaScript 密集型和动态内容。这些工具可确保即使是最复杂的网站也能进行安全、可扩展且可靠的数据收集。