来自 Node 的带有分块响应流的 Axios 请求
Posted
技术标签:
【中文标题】来自 Node 的带有分块响应流的 Axios 请求【英文标题】:Axios request with chunked response stream from Node 【发布时间】:2020-03-16 14:55:11 【问题描述】:我在 React 中有一个客户端应用程序,在 Node 中有一个服务器(使用 Express)。 在服务器端,我有一个类似以下的端点(不是真正的端点,只是我在做什么的一个想法):
function endpoint(req, res)
res.writeHead(200,
'Content-Type': 'text/plain',
'Transfer-Encoding': 'chunked'
);
for(x < 1000)
res.write(some_string + '\n');
wait(a_couple_of_seconds); // just to make process slower for testing purposes
res.end();
这是完美的,我的意思是,当我调用这个端点时,我会收到包含所有 1.000 行的整个流。
问题是我无法设法按块获取这些数据(对于每个“写入”或一堆“写入”),以便在我收到它们后立即在前端显示..(想想在我从端点调用中获取行后立即显示行的表)
在前端,我使用 Axios 调用 API,代码如下:
async function getDataFromStream(_data): Promise<any>
const data, headers = await Axios(
url: `http://the.api.url/endpoint`,
method: 'GET',
responseType: 'stream',
timeout: 0,
);
// this next line doesn't work. it says that 'on' is not a function
data.on('data', chunk => console.log('chunk', chunk));
// data has actually the whole response data (all the rows)
return Promise.resolve();
问题是 Axios 调用在调用服务器上的“res.end()”之后返回整个数据对象,但我需要在服务器开始发送带有行的块时立即获取数据(在每次 res.write 或服务器认为已准备好发送一些块时)。
我也尝试过不使用 await 并在 axios 调用的 'then()' 处获取 promise 的值,但这是相同的行为,'data' 值与所有 '一旦服务器执行 'res.end()'
那么,我在这里做错了什么?也许这对于 Axios 或 Node 是不可能的,我应该使用 websockets 之类的东西来解决它。 任何帮助都将不胜感激,因为我阅读了很多但还没有找到可行的解决方案。
【问题讨论】:
【参考方案1】:对于任何对此感兴趣的人,我最终做的是以下内容:
在客户端,我使用了允许处理下载进度事件的 Axios onDownloadProgress 处理程序。
所以,我实现了这样的东西:
function getDataFromStream(_data): Promise<any>
return Axios(
url: `http://the.api.url/endpoint`,
method: 'GET',
onDownloadProgress: progressEvent =>
const dataChunk = progressEvent.currentTarget.response;
// dataChunk contains the data that have been obtained so far (the whole data so far)..
// So here we do whatever we want with this partial data..
// In my case I'm storing that on a redux store that is used to
// render a table, so now, table rows are rendered as soon as
// they are obtained from the endpoint.
).then(( data ) => Promise.resolve(data));
【讨论】:
dataChunk
包含到目前为止的所有块,因为我已经处理了以前的块,所以我只需要“新”块。有什么方法可以获取新的块?
您是否可以控制服务器上的数据格式?如果是这样,您可以创建类似管道分隔的字符串,客户端可以解析该字符串以获取“最新”事件。下面是我如何解析看起来像 'event1|event2|event3|...' 的数据的示例: return axios.post('some/end/point', payload, onDownloadProgress: (progressEvent) => //RegEx获取 | 分隔字符串中的最后一项// const message = /\|([^|]+)\|$/.exec(progressEvent.currentTarget.response); EventBus.$emit('show-feedback', message ? 消息[1] : '', '成功'); );以上是关于来自 Node 的带有分块响应流的 Axios 请求的主要内容,如果未能解决你的问题,请参考以下文章