https.request返回不完整的流



https.request返回正确的数据,但当我将响应管道传输到文件中时,它是不完整的,并且在一开始就丢失了很多。

我如何使用https.request:

import client from "https";
const _request = (url, options, timeout) => {
let data = '';
const httpOptions = {};
const parsedUrl = new URL(url);
const hostname = parsedUrl.hostname;
const port = parsedUrl.port;
const path = parsedUrl.pathname;
const params = parsedUrl.search;
httpOptions["hostname"] = hostname;
httpOptions["port"] = port;
httpOptions["path"] = path + params;
httpOptions["method"] = options.method.toUpperCase() || "GET";
return new Promise((resolve, reject) => {
const req = client.request(httpOptions, (res) => {
if (options.stream === true) resolve(res);
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
resolve({
status: res.statusCode,
statusText: res.statusMessage,
data: data,
});
});
res.on("error", (err) => {
reject(err);
});
});
req.end();
});
};

我如何尝试流式传输响应:

import client from "./index.js";
import { createWriteStream } from "fs";
const response = await client("an.api.that/returns-plain-text", {
method: "GET",
stream: true
}, 5000);
const writeStream = createWriteStream("./test.txt");
response.pipe(writeStream);

我已经尝试过将if (options.stream === true) resolve(res);移动到req.on("end")中,但是这导致了相同的问题。

谢谢!

语句res.on("data", ...)使响应立即开始发出data事件。如果你写一些类似的东西

_request(url, {stream: true}, timeout)
.then(function(res) {
res.pipe(createWriteSteam(...));
});

那么,当到达res.pipe语句时,res可能已经发出了一些数据,这些数据随后会丢失(因此,正如您所观察到的,响应的开头将丢失(。

为了防止data事件的过早发出,您可以明确地暂停流:

if (options.stream === true) {
res.pause();
resolve(res);
}

最新更新