开发者

Browser fetch API stream doesn't work on server

开发者 https://www.devze.com 2022-12-07 21:45 出处:网络
As I explained in a previous question I have a FastAPI endpoint that returns a StreamingRespo开发者_如何学运维nse response that is then consumed by a React application using fetch().body.getReader() A

As I explained in a previous question I have a FastAPI endpoint that returns a StreamingRespo开发者_如何学运维nse response that is then consumed by a React application using fetch().body.getReader() API.

The problem I'm facing appears when I open my React application, select the image (s) using Uppy and send it to my FastAPI endpoint, locally it works just fine and the images are returned as a stream response:

Browser fetch API stream doesn't work on server

Browser fetch API stream doesn't work on server

But when I deploy my application on Heroku or Render the rendered response is all broken:

Browser fetch API stream doesn't work on server

Browser fetch API stream doesn't work on server

Adding more context to my previous question I'm rendering the stream using an async generator:

async function* submit({data}) {
    const formData = new FormData()

    data?.current?.files?.successful.map(image =>
        formData.append('images', image.data)
    )

    formData.append('language', data.current.language.code)

    try {
        const response = await fetch(
            'endpoint',
            {
                method: 'POST',
                body: formData
            }
        )

        const reader = response.body.getReader()

        while (true) {
            const { value, done } = await reader.read()

            if (done) break

            const base64 = `data:${response.headers.get(
                'content-type'
            )};base64,${btoa(String.fromCharCode(...new Uint8Array(value)))}`

            yield base64
        }
    } catch (error) {
        // ...
    }
}

That is called when the "Gallery" component in the screenshot is rendered:

const [images, setImages] = useState([])

    useEffect(() => {
        ;(async () => {
            for await (const image of await translateSubmit({
                data
            })) {
                setImages(previous => [...previous, image])
            }
        })()

        // eslint-disable-next-line
    }, [])

I was expecting to get the same result in the server when the application is deployed, but it just doesn't work as it should and I'm not sure how to approach the problem. Any tips?

0

精彩评论

暂无评论...
验证码 换一张
取 消