ofetch icon indicating copy to clipboard operation
ofetch copied to clipboard

`Body has already been consumed.` with `$fetch.raw`

Open ppodds opened this issue 3 years ago • 8 comments

const resp = await $fetch.raw("https://test.com/blob");
console.log(resp.blob()); // caused error

get Failed to execute 'blob' on 'Response': body stream already read

still can get data by resp._data

ppodds avatar Jun 24 '22 06:06 ppodds

@ppodds

ohfetch package has been updated since you created this issue, so would you try it again with the latest version? If you find it still does not work, please reopen this issue with a reproduction.

nozomuikuta avatar Jan 11 '23 20:01 nozomuikuta

I have the exact same issue with latest ofetch release (1.1.1). Reproduction is quite simple :

// Run on browser
import { ofetch } from 'ofetch';
const response = await ofetch.raw("/favicon.png", { responseType: "blob" });
await response.blob(); // <- trigger TypeError: Response.blob: Body has already been consumed.

It seems ofetch.raw already parse the response and put it in response._data.

The exact same code with native fetch instead of ofetch works perfectly

felicienfrancois avatar Jun 26 '23 08:06 felicienfrancois

@ppodds @NozomuIkuta can you reopen this issue or should I create a new one ?

felicienfrancois avatar Jun 26 '23 08:06 felicienfrancois

@felicienfrancois

I just reopened this issue for now. Would you provide a working reproduction in Stackblitz or something else?

nozomuikuta avatar Jun 26 '23 08:06 nozomuikuta

@NozomuIkuta i was willing to do it but it seems that it is harder than i expected to use ofetch in a vanilla browser project, for 2 reasons :

  • ofetch is not available on cdnjs or alternative cdns
  • there are compilation issues in browser compiled projects because it reference node:xxx dependencies (Example : https://stackblitz.com/edit/js-tjzqmn)

Is there a stackblitz template i can start from ?

felicienfrancois avatar Jun 26 '23 09:06 felicienfrancois

@NozomuIkuta here a working reproduction on node https://stackblitz.com/edit/stackblitz-starters-zyf8ky

felicienfrancois avatar Jun 26 '23 09:06 felicienfrancois

$fetch always consumes body. As per docs, you can directly use res._data:

import { ofetch } from 'ofetch';

const res = await ofetch.raw('https://fel.icien.fr/favicon.png', {
  responseType: 'blob',
});

console.log(res._data); // <-- Blob {}

pi0 avatar Aug 23 '23 18:08 pi0

$fetch always consumes body. As per docs, you can directly use res._data:

Is this also the recommended way to access the data inside onResponseError handlers to e.g. access error reasons in JSON form send by the backend? Having to use _data (where the underscore usually notes private, undocumented, fragile interfaces often without any stability guarantees between library versions) seems very hacky and is commonly configured to raise a warning by linters.

septatrix avatar Sep 17 '23 21:09 septatrix