使用 Axios 从 Express 应用程序返回流 - “提供的值‘流’不是 XMLHttpRequestResponseType 类型的有效枚举值。”

Cer*_*ean 8 node.js express axios

我正在学习 Node、Express 和 React,并尝试将用于调用 Express API 的简单通用 Fetch 方法转换为 Axios。当我希望 Axios 自动将结果作为 JSON 数据返回时,我已经让 Axios 工作了,但在这里我希望它返回一个ReadableStream. 从文档来看,它应该很简单:只需将字段添加到responseType:'stream'config我不断收到错误The provided value 'stream' is not a valid enum value of type XMLHttpRequestResponseType. 我看到其他人也遇到了这个问题(请参阅https://github.com/axios/axios/issues/1474)但我没有没有看到任何解决方案。有谁知道是否有,或者我是否做错了什么?相关代码如下。感谢您的任何见解!

const logic = {

 _call(path, method, headers, body, expectedStatus) {
        const config = { method,responseType:'stream', url: `http://localhost:8080/${path}`}

        if (headers) config.headers = headers
        if (body) config.data = body

        return axios( config)
            .then(res => {
                if (res.status === expectedStatus) {
                    return res
                } else
                    return res
                        .then(({ message }) => {
                            throw new Error(message)
                        })
            })
    }
}
Run Code Online (Sandbox Code Playgroud)

Ani*_*nna 4

如果您明确需要 Axios 中的流,这个答案可能值得检查。

也就是说,我更喜欢默认值fetch以获得更大的灵活性。如果有人感兴趣,这里有一个客户端方法来获取流作为可迭代块的列表。

从上到下,最终的调用如下所示:

const stream = await generateStream()
for await (const chunk of stream) {
  console.log(chunk)
}
Run Code Online (Sandbox Code Playgroud)

generateStream函数是执行实际 API 调用的函数,如下所示:

export const generateStream = async (): Promise<AsyncIterable<string>> => {
  const response = await fetch(
    'http://localhost:5000/api/stream/dummy?chunks_amount=50',
    {
      method: 'GET',
    }
  )
  if (response.status !== 200) throw new Error(response.status.toString())
  if (!response.body) throw new Error('Response body does not exist')
  return getIterableStream(response.body)
}
Run Code Online (Sandbox Code Playgroud)

最后,这是getIterableStream在加载字节块时读取字节块并将其解码为字符串的函数:

export async function* getIterableStream(
  body: ReadableStream<Uint8Array>
): AsyncIterable<string> {
  const reader = body.getReader()
  const decoder = new TextDecoder()

  while (true) {
    const { value, done } = await reader.read()
    if (done) {
      break
    }
    const decodedChunk = decoder.decode(value, { stream: true })
    yield decodedChunk
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意 中的星号async function* getIterableStream。此语法定义了一个异步生成器函数。