如何在不使用require的情况下用Node.js发起HTTP GET请求
Node.js 8.11.1版本下不使用
require('http')实现带自定义请求头的GET请求方案 存在可行实现,但有前提限制。
HTTP本身是基于TCP的纯文本应用层协议,你只要遵循HTTP 1.1的报文规范,用Node.js的net(HTTP场景)或tls(HTTPS场景)核心模块建立底层连接、手动拼接发送请求报文、解析返回报文即可实现完整的GET请求能力,全程不需要引入http/https模块。
实现步骤
- 按照HTTP协议格式拼接GET请求报文,结构如下:
注意报文末尾必须有两个连续的请求方法 请求路径 HTTP版本\r\n Host: 目标域名\r\n 自定义请求头1: 值\r\n 自定义请求头2: 值\r\n Connection: close\r\n \r\n\r\n标识请求头结束,不可省略。 - 使用
net.connect连接目标服务器的80端口(HTTPS用tls.connect连443端口),连接建立后发送拼接好的请求报文 - 监听TCP连接的
data事件接收响应数据,end事件触发后拆分解析响应报文,分别提取状态码、响应头、响应体即可
可运行示例代码
const net = require('net'); // 请求配置 const reqConfig = { host: 'example.com', port: 80, path: '/', headers: { 'User-Agent': 'MyCustomClient/1.0', 'Accept': 'application/json', 'X-Test-Header': 'custom-value' } }; // 拼接请求报文 let rawReq = `GET ${reqConfig.path} HTTP/1.1\r\n`; rawReq += `Host: ${reqConfig.host}\r\n`; Object.entries(reqConfig.headers).forEach(([k, v]) => { rawReq += `${k}: ${v}\r\n`; }); rawReq += 'Connection: close\r\n\r\n'; // 发起请求 const socket = net.connect(reqConfig.port, reqConfig.host, () => { socket.write(rawReq); }); let rawRes = ''; socket.on('data', chunk => { rawRes += chunk.toString(); }); socket.on('end', () => { // 解析响应 const [headersRaw, body] = rawRes.split('\r\n\r\n'); const headerLines = headersRaw.split('\r\n'); // 解析状态行 const statusMatch = headerLines.shift().match(/HTTP\/1\.\d (\d+) (.+)/); const statusCode = +statusMatch[1]; const statusText = statusMatch[2]; // 解析响应头 const resHeaders = {}; headerLines.forEach(line => { const [k, v] = line.split(': '); resHeaders[k.toLowerCase()] = v; }); // 输出结果 console.log('状态码:', statusCode); console.log('状态信息:', statusText); console.log('响应头:', resHeaders); console.log('响应体:', body); }); socket.on('error', err => { console.error('请求出错:', err); });
注意事项
- 上述实现仅为最简Demo,生产环境使用需要额外兼容chunked编码响应、重定向、超时处理、编码自动识别等场景
- 如果你要求的「仅通过JS实现」是完全不使用任何Node.js核心模块,仅用ECMAScript标准语法实现,那么不存在可行方案:标准JS本身没有定义任何网络IO相关的API,所有网络能力都是运行环境(Node.js/浏览器)通过扩展接口提供的,没有绕过的可能性
内容的提问来源于stack exchange,提问作者asudhak
相关产品推荐
相关产品推荐

