Node.js使用https模块发送GET请求返回乱码字符是什么原因?
问题原因
- 核心问题是未处理服务端返回的压缩响应:绝大多数公网接口会默认使用gzip/deflate/br等算法压缩响应内容,你直接将二进制压缩流按utf8编码读取,就会输出乱码,和你设置的URL对象无关。
- 请求头配置错误:GET请求没有请求体,不需要设置
Content-Type请求头,该字段用于声明请求体的格式;你需要补充Accept头明确告知服务端你期望接收的内容类型为application/json,也可以补充Accept-Encoding字段指定你支持的压缩格式,或者传入identity要求服务端返回未压缩的内容。 - 代码逻辑存在疏漏:你注释中也标注了,
data事件的回调内没有将接收到的chunk拼接到str变量上,最终end事件触发时打印的str永远是空字符串。
修复方案
你可以直接用Node.js内置的zlib模块处理压缩响应,以下是修复后的示例代码:
const https = require('https') const zlib = require('zlib') const { URL } = require('url') const url = new URL("你的有效URL") https.get({ host: url.hostname, path: url.pathname, headers: { "Accept": "application/json", // 可以指定接受的压缩格式,也可以设为identity要求不压缩 "Accept-Encoding": "gzip, deflate, br" } }, (res) => { // 根据响应头的content-encoding判断是否需要解压 const encoding = res.headers['content-encoding'] let stream = res if (encoding === 'gzip') { stream = res.pipe(zlib.createGunzip()) } else if (encoding === 'deflate') { stream = res.pipe(zlib.createInflate()) } else if (encoding === 'br') { stream = res.pipe(zlib.createBrotliDecompress()) } stream.setEncoding('utf8') let str = "" stream.on("data", c => { str += c }) stream.on("end", () => { console.log(str) // 如果返回的是pre标签包裹的JSON,还需要提取pre内的内容再解析 // 示例提取逻辑:const jsonStr = str.match(/<pre>(.*?)<\/pre>/s)?.[1] // 然后用JSON.parse(jsonStr)拿到JSON对象 }) })
如果不希望处理压缩逻辑,也可以直接把Accept-Encoding请求头设为identity,大部分服务端会返回未压缩的响应,就不需要额外做解压处理了。
内容的提问来源于stack exchange,提问作者MrMythical
相关产品推荐
相关产品推荐

