electron 使用Fetch API和fs.createWriteStream将响应流传输到文件

e0bqpujr  于 2022-12-16  发布在  Electron
关注(0)|答案(3)|浏览(352)

我正在创建一个电子应用程序,我想流图像到文件(所以基本上下载它)。
我希望使用本地API,因为请求模块将是一个很大的开销。
但是在响应上没有管道方法,所以我不能执行如下操作

fetch('https://imageurl.jpg')
    .then(response => response.pipe(fs.createWriteStream('image.jpg')));

那么,如何将fetchfs.createWriteStream结合起来呢?

myss37ts

myss37ts1#

我让它工作了。我做了一个函数,把响应转换成一个可读的流。

const responseToReadable = response => {
    const reader = response.body.getReader();
    const rs = new Readable();
    rs._read = async () => {
        const result = await reader.read();
        if(!result.done){
            rs.push(Buffer.from(result.value));
        }else{
            rs.push(null);
            return;
        }
    };
    return rs;
};

所以有了它,我可以

fetch('https://imageurl.jpg')
    .then(response => responseToReadable(response).pipe(fs.createWriteStream('image.jpg')));
carvr3hs

carvr3hs2#

Fetch实际上不能与nodejs Streams一起使用,因为浏览器中的Stream API与nodejs提供的API不同,即您不能将浏览器流通过管道传输到nodejs流中,反之亦然。
electron-fetch模块似乎为您解决了这个问题。或者您可以查看以下答案:https://stackoverflow.com/a/32545850/2016129可以下载文件,而无需节点集成。
还有needle,这是一个较小的替代方案,可以替代较大的请求,当然它支持流。

fae0ux8s

fae0ux8s3#

我想今天的答案是nodejs 18+

node -e 'fetch("https://github.com/stealify").then(response => stream.Readable.fromWeb(response.body).pipe(fs.createWriteStream("./github.com_stealify.html")))'

在上面的例子中,我们使用-e标志,它告诉nodejs执行我们的cli代码,我们在这里下载一个interristing项目的页面,并将其另存为github.com在当前工作目录中,下面的代码在nodejs .mjs文件中显示了相同的内容
使用CommonJS的Cli示例

node -e 'fetch("https://github.com/stealify").then(({body:s}) =>
 stream.Readable.fromWeb(s).pipe(fs.createWriteStream("./github.com_stealify.html")))'

fetch.cjs

fetch("https://github.com/stealify").then(({body:s}) => 
 require("node:stream").Readable.fromWeb(s)
  .pipe(require("node:fs").createWriteStream("./github.com_stealify.html")));

使用ESM的Cli示例

node --input-type module -e 'stream.Readable.fromWeb(
 (await fetch("https://github.com/stealify")).body)
  .pipe(fs.createWriteStream("./github.com_stealify.html"))'

获取_tla_no_tli.mjs

(await import("node:stream")).Readable.fromWeb(
 (await fetch("https://github.com/stealify")).body).pipe(
  (await import("node:fs")).createWriteStream("./github.com_stealify.html"));

fetch.mjs

import stream from 'node:stream';
import fs from 'node:fs';
stream.Readable
  .fromWeb((await fetch("https://github.com/stealify")).body)
  .pipe(fs.createWriteStream("./github.com_stealify.html"));

参见:https://nodejs.org/api/stream.html#streamreadablefromwebreadablestream-options

相关问题