HTTP 客户端在 JavaScript 中:在 Node.js 中正确发起请求
现代 Web 开发离不开与远程服务器的交互。无论是从 REST API 获取数据、发送表单还是上传文件——HTTP 请求是所有集成的基础。如果您在 Node.js 上进行开发,那么您有几种强大的工具来创建 HTTP 客户端。在本文中,我们将探讨如何正确发起请求:从内置模块到流行库,重点介绍错误处理、超时和代码可读性。
我们将讨论三种主要方法:内置模块 http/https、现代 fetch(在 Node.js 18+ 中可用)以及传奇库 axios。对于每种方法,您都会找到实际示例和建议。
1. 内置模块 http/https:经典之作
Node.js 从一开始就包含了 http 和 https 模块用于处理网络请求。这是最低级别的方式,可以完全控制整个过程。然而,它需要更多的代码来处理响应。
使用 https 模块的 GET 请求示例:
const https = require('https');
function getUsers() { return new Promise((resolve, reject) => { const options = { hostname: 'jsonplaceholder.typicode.com', path: '/users', method: 'GET', headers: { 'Content-Type': 'application/json' } };
const req = https.request(options, (res) => { let data = '';
// 逐块收集数据 res.on('data', (chunk) => { data += chunk; });
// 当响应完全接收时 res.on('end', () => { if (res.statusCode >= 200 && res.statusCode < 300) { resolve(JSON.parse(data)); } else { reject(new Error(`HTTP Error: ${res.statusCode}`)); } }); });
// 处理网络错误 req.on('error', (err) => { reject(err); });
// 超时以防挂起 req.setTimeout(5000, () => { req.destroy(); reject(new Error('Request timeout')); });
req.end(); });}
// 使用getUsers() .then(users => console.log('Users:', users.length)) .catch(err => console.error('Error:', err.message));优点:
- 无需安装额外的包。
- 完全控制连接的每个阶段。
缺点:
- 大量样板代码。
- 手动处理数据块和组装响应体。
- 没有包装器的情况下使用 Promise 不方便。
如果您正在编写用于网络操作的库,或者需要最大性能且无需额外依赖,那么这种方法是有道理的。在其他情况下,最好使用更高级别的解决方案。
2. Fetch API:现代标准
从 Node.js 18 开始,fetch 成为了内置函数,使其成为 HTTP 请求的主要工具。它基于 Promise,具有简洁直观的语法。
使用 fetch 的 POST 请求示例:
async function createPost() { const url = 'https://jsonplaceholder.typicode.com/posts'; const newPost = { title: 'HTTP 客户端在 JavaScript 中', body: '正确发起请求', userId: 1 };
try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(newPost) });
// 检查响应状态 if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); }
const data = await response.json(); console.log('Created post ID:', data.id); return data; } catch (error) {