在网络请求中,流(stream)表示持续接收数据的过程。使用流,可以逐步获取服务器响应,而不是等待整个响应完成后一次性获取。
axios 从 0.12 版本开始支持流式请求。在 axios 中,可以通过响应对象的 data 事件监听流式响应。
扩展:如果你想尝试更便捷、高效的方式来调试 API,那么可以使用 Apifox。Apifox 提供了直观的界面,让你轻松管理并调试项目接口。
Axios 流式请求写法
axios 流式请求主要有两种写法:
创建流并 Pipe 到 Writable Stream
通过调用 axios() 方法发起请求,获取到响应对象后,监听 data 事件,然后 pipe 数据到一个 Writable Stream 中,如 fs.createWriteStream。
const axios = require('axios');
const fs = require('fs');
const writer = fs.createWriteStream('example.pdf');
axios({
method: 'get',
url: '/example.pdf',
responseType: 'stream'
})
.then(response => {
response.data.pipe(writer);
});
手动监听 data 事件
通过调用 axios() 方法发起请求,获取到响应对象后,监听 data 事件,在事件回调中手动处理流数据:
const axios = require('axios');
axios({
method: 'get',
url: '/example.pdf',
responseType: 'stream'
})
.then(response => {
response.data.on('data', (chunk) => {
// 处理流数据的逻辑
});
response.data.on('end', () => {
// 数据接收完成的逻辑
});
});
实践案例
下面是一个简单的示例,使用 Express 搭建一个服务器,通过 axios 发起流式请求,将响应数据保存到一个文件中,详细步骤和细节如下:
1.首先需要先安装 axios 和 express 模块:
npm install axios
npm install express
2.例子中需要一个文件 file.txt 作为服务器端的数据源,你可以自行准备这个文件(文件内容不做规定,可随便填点内容进去)
3.新建一个 server.js 文件,在 server.js 中,使用 express 启动一个 web 服务器,并定义一个 /stream 的路由,代码如下:
// 引入express模块
const express = require('express');
// 创建express app
const app = express();
// 定义/stream路由
app.get('/stream', (req, res) => {
// 读取file.txt文件并传给响应
const stream = fs.createReadStream('file.txt');
stream.pipe(res);
});
// 启动服务器,监听3000端口
app.listen(3000);
注:服务器启动命令为 node server.js
这段代码使用 fs.createReadStream() 创建了一个 file.txt 文件的读取流,并使用 pipe 方法将这个流输出到响应对象 res 中。
4.创建一个 client.js 文件,在 client.js 中,使用 axios 发起请求:
// 引入axios模块
const axios = require('axios');
const fs = require('fs');
const writer = fs.createWriteStream('output.txt');
// 发起GET请求到/stream路由
axios({
method: 'GET',
url: 'http://localhost:3000/stream',
responseType: 'stream' // 声明响应类型为流
})
.then(response => {
// 通过data事件获取响应流
response.data.pipe(writer);
});
注:客户端启动命令为 node client.js
客户端通过 axios 发起请求,并通过 response.data.pipe() 将响应流 pipe 到一个文件写入流中。
实践案例中生成了 output.txt 文件,说明实现了文件的流传输:
通过 Apifox 调试后端接口
当我们作为前端开发人员使用 Axios 来进行接口请求时,有时候我们可能会遇到一个问题:等待后端开发人员提供接口。这往往会导致我们在开发时遇到阻碍,进而影响项目的进度。不过,我了解到一个非常实用的工具可以解决这个问题,它就是 Apifox。
Apifox = Postman + Swagger + Mock + JMeter,Apifox 支持调试 http(s)、WebSocket、Socket、gRPC、Dubbo 等协议的接口,并且集成了 IDEA 插件。在后端人员写完服务接口时,测试阶段可以通过 Apifox 来校验接口的正确性,图形化界面极大的方便了项目的上线效率。
更为重要的是,Apifox 能够 Mock 数据,其集成了 Mock.js 库,允许你自定义规则,并且可以编写脚本,强大的 Mock 功能可以让前端开发人员不再苦苦等待后端提供接口,自己就能提前造各种各样的数据出来,可视化操作让你点点鼠标就能生成可观的人性化数据。
在本文的例子中,就可以通过 Apifox 来测试接口。新建一个项目后,在项目中选择“调试模式”,填写请求地址后即可快速发送请求,并获得响应结果,上文的实践案例如图所示:
提示和注意事项
- responseType 必须设置为 'stream',来表示响应类型为流。
- 在 pipe 数据时,必须正确处理流事件,包括 finish 和 error 事件。
- 流请求不支持 timeout、cancel token 和 validateStatus 等配置。
- 流只能使用一次,如果需要再次读取,需重新发起请求。
- 流数据可能会乱序到达,需要正确处理数据顺序。
总结
Axios 通过监听响应对象的 data 事件,可以实现流式请求,主要的写法有直接 pipe 流和手动监听事件两种。使用流可以实现大文件或数据的流传输,有效管理内存,提高传输效率。但需要注意正确处理流事件。
知识扩展:
参考链接:
- Axios API文档 - 请求配置:https://github.com/axios/axios#request-config
- Node.js Stream手册:https://nodejs.org/dist/latest-v16.x/docs/api/stream.html