Получение потокового ответа FastApi через JS

#javascript #fetch #streaming #fastapi

#javascript #извлечение #потоковая передача #fastapi

Вопрос:

Я пытаюсь получить и консоль.регистрируйте мои данные, передаваемые из FastApi через StreamedResponse, используя выборку, но я не могу заставить его работать. Chrome говорит Cannot read properties of null (reading 'getReader') , что значение because response.body равно нулю. Что я делаю не так?

Сервер

 async def foo():
    for i in range(5):
        time.sleep(1)
        yield b'foobar'

@app.get('/bar')
async def bar():
    return StreamingResponse(foo(), media_type='text/plain')
 

клиент

 async function buttonclick() {
        let url = 'http://localhost:8000/bar';

        let options = {
            mode: 'no-cors',
            method: 'GET'
        }

        fetch(url, options)
            .then(processChunkedResponse)
            .then(onChunkedResponseComplete)
            .catch(onChunkedResponseError);

    }


    function onChunkedResponseComplete(result) {
        console.log('all done!', result)
    }

    function onChunkedResponseError(err) {
        console.error(err)
    }

    function processChunkedResponse(response) {
        var text = '';
        var reader = response.body.getReader()
        var decoder = new TextDecoder();

        return readChunk();

        function readChunk() {
            return reader.read().then(appendChunks);
        }

        function appendChunks(result) {
            var chunk = decoder.decode(result.value || new Uint8Array, {stream: !result.done});
            console.log('got chunk of', chunk.length, 'bytes')
            text  = chunk;
            console.log('text so far is', text.length, 'bytesn');
            if (result.done) {
                console.log('returning')
                return text;
            } else {
                console.log('recursing')
                return readChunk();
            }
        }
    }
 

Ответ №1:

A no-cors Request.mode возвращает непрозрачный ответ и «JavaScript не может получить доступ к каким-либо свойствам результирующего ответа». Ваш сервер может предоставить заголовок Access-Control-Allow-Origin , а клиент должен использовать стандартную cors выборку.

Кроме того, вам может потребоваться внести это изменение, чтобы гарантировать возврат обещания:

 if (result.done) {
  //return text
  return Promise.resolve(text)
}