最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to pipe to Next.js 13 api response? - Stack Overflow

programmeradmin0浏览0评论

Earlier, I was able to pipe the response of another api call to Next.js api response as follows

export default async function (req, res) {
    // prevent same site/ obfuscate original API
    // some logic here 
    fetch(req.body.url).then(r => {
      r.body.pipe(res);
    }).catch(err => {
      console.log(err);
      res.status(500).send("Invalid Url");
    })
}

It worked fine. But now the response.body from fetch API does not have pipe method. Rather, it has pipeTo and pipeThrough methods. And the Next.js res:NextApiResponse, is not assignable to WritableStream.

I also tried creating blob (await r.blob()) and using res.send(blob) and res.send(blob.strem()). It seems to work at first but the data received by front end is not proper (Basically fetch().then((res) => res.blob()).then((blob) => URL.createObjectURL(blob))) will give corrupt result).

Earlier, I was able to pipe the response of another api call to Next.js api response as follows

export default async function (req, res) {
    // prevent same site/ obfuscate original API
    // some logic here 
    fetch(req.body.url).then(r => {
      r.body.pipe(res);
    }).catch(err => {
      console.log(err);
      res.status(500).send("Invalid Url");
    })
}

It worked fine. But now the response.body from fetch API does not have pipe method. Rather, it has pipeTo and pipeThrough methods. And the Next.js res:NextApiResponse, is not assignable to WritableStream.

I also tried creating blob (await r.blob()) and using res.send(blob) and res.send(blob.strem()). It seems to work at first but the data received by front end is not proper (Basically fetch().then((res) => res.blob()).then((blob) => URL.createObjectURL(blob))) will give corrupt result).

Share Improve this question asked Dec 6, 2022 at 8:46 Mayank Kumar ChaudhariMayank Kumar Chaudhari 18.8k13 gold badges67 silver badges155 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 3

There exists the Readable.fromWeb() experimental API that transforms fetch() ReadableStream into nodejs stream. Seems to work in node v18.14.0.

import { Readable } from 'node:stream';

export default async function (req, res) {
    // prevent same site/ obfuscate original API
    // some logic here 
    fetch(req.body.url).then(r => {
      Readable.fromWeb(r.body).pipe(res);
    }).catch(err => {
      console.log(err);
      res.status(500).send("Invalid Url");
    })
}

Here's the trick that worked like a charm!

const https = require("https");

export default async function handler(req, res) {
   try {
      const url = `your-url`;
      res.status(200);
      https.get(url, (response) => {
        response.pipe(res);
        response.on("finish", res.end);
      });
    } catch (err) {
      console.log(err);
      res.status(500).send("Invalid Url");
    }
}

Update

The above trick works great for some simple cases but fails when there are redirects.

The Readable API works better than this as suggested by Klesum

import { Readable } from 'node:stream';

export default async function (req, res) {
    fetch(req.body.url).then(r => {
      Readable.fromWeb(r.body).pipe(res);
    })
}

TypeScript plains about this, but you can ignore ts warnings for that line // @ts-ignore and it would work fine.

发布评论

评论列表(0)

  1. 暂无评论