如何在Angular中获取数据流?请求解析报错及EventSource连接失败问题
问题描述
通过curl localhost:8080/slow/5可正常获取逐行输出的数据流:
C:\Users\user>curl localhost:8080/slow/5 5 4 3 2 1 0 C:\Users\user>
尝试用Angular标准HTTP Get请求时,5秒后触发报错:
constructor( private http: HttpClient, private ngzone: NgZone ) { this.http.get('/slow/5').subscribe(x => console.log(x)) }
错误信息:
error: Object { error: SyntaxError, text: "5\n4\n3\n2\n1\n0\n" }
尝试使用EventSource方法但无法建立连接,代理配置正常,寻求解决方案。
解决方案
1. 修复HttpClient请求报错
HttpClient默认会将响应解析为JSON格式,但你的接口返回的是纯文本逐行数据,并非合法JSON,因此抛出语法错误。需显式指定响应类型为text:
this.http.get('/slow/5', { responseType: 'text' }).subscribe({ next: (text) => { // 拆分所有行并输出 const lines = text.trim().split('\n'); lines.forEach(line => console.log(line)); }, error: (err) => console.error(err) });
注意:这种方式仍会等待整个响应完成(5秒后)才返回所有数据,无法实现实时流式展示。
2. 原生XHR实现实时流式获取
直接使用XMLHttpRequest监听progress事件,可实时获取流式传输的分片数据:
constructor(private ngZone: NgZone) { const xhr = new XMLHttpRequest(); xhr.open('GET', '/slow/5'); xhr.responseType = 'text'; let receivedData = ''; xhr.addEventListener('progress', () => { // 提取本次新增的分片数据 const newData = xhr.response.substring(receivedData.length); receivedData = xhr.response; // 拆分新行并输出(跳过空行) const lines = newData.trim().split('\n'); lines.forEach(line => { if (line) { this.ngZone.run(() => { console.log(line); }); } }); }); xhr.addEventListener('load', () => { console.log('数据流传输结束'); }); xhr.addEventListener('error', (err) => { console.error('请求错误:', err); }); xhr.send(); }
使用ngZone.run是因为XHR事件触发在Angular变更检测域外,若后续需更新UI,可保证变更检测正常执行。
3. EventSource连接失败的排查与修复
EventSource要求服务器必须返回符合SSE(Server-Sent Events)规范的响应:
- 响应头需设置
Content-Type: text/event-stream和Cache-Control: no-cache - 消息格式必须以
data:开头,空行结尾(例如data: 5\n\n)
你的当前接口输出的是纯数字逐行,不符合SSE格式,因此EventSource无法识别。若无法修改服务器端输出格式,建议使用上述XHR流式方案;若能修改服务器,则调整输出格式后再尝试EventSource。
内容的提问来源于stack exchange,提问作者Heligo
相关产品推荐
相关产品推荐

