You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解析XMLHttpRequest响应并获取SSE最后推送值?

问题:如何从SSE推送的全量响应中提取最后一条数据

我有一个返回SseEmitter的Web服务,用于实现加载进度条,当前使用以下XMLHttpRequest方法接收推送:

static async synchronize(component: Vue) {
    let xhr = new XMLHttpRequest();
    xhr.open('PATCH', 'myUrl.com');
    xhr.responseType = "text"
    xhr.setRequestHeader('Authorization', 'mySessionToken')
    xhr.setRequestHeader("Content-Type", "text/event-stream")
    xhr.onload = function () {
        if (this.status >= 200 && this.status < 300) {
            resolve(xhr.response)
        } else {
                reject({status: this.status, statusText: xhr.statusText})
        }
    }
    xhr.onerror = function () {reject({status: this.status, statusText: xhr.statusText})}
    xhr.onreadystatechange = function() {if (xhr.readyState == XMLHttpRequest.DONE) { alert(xhr.responseText) }}
    xhr.onprogress = function(onEvent) {
    console.log(xhr.response)
    }
    xhr.send()  
}

目前该方法可运行,但xhr.response返回包含所有历史推送内容的字符串,格式如下:

data:"{ hello: '1' }"
data:"{ hello: '2' }"
...
//以此类推直到100

每次推送事件触发时,响应会返回全部历史状态记录,内容随推送次数增加而变大。尝试使用JSON.parse解析时报错,推测是响应格式不符合JSON规范。请问是否有办法仅获取该响应中的最后一条推送值?


解决方案

方法1:优化XMLHttpRequest的响应处理

针对当前XHR返回的全量数据,通过字符串分割提取最后一条推送,并修正JSON格式后解析:

修改onprogress事件处理逻辑:

xhr.onprogress = function(onEvent) {
  const fullResponse = xhr.response;
  if (!fullResponse) return;

  // 1. 按换行分割所有推送记录,过滤空行
  const lines = fullResponse.split('\n').filter(line => line.trim() !== '');
  if (lines.length === 0) return;

  // 2. 获取最后一条推送记录
  const lastLine = lines[lines.length - 1];

  // 3. 提取并修正JSON格式:去掉data前缀、替换单引号为双引号
  const jsonStr = lastLine
    .replace(/^data:"/, '') // 移除开头的data:"
    .replace(/"$/, '')      // 移除结尾的"
    .replace(/'/g, '"');    // 替换单引号为标准JSON双引号

  // 4. 解析JSON并使用
  try {
    const latestData = JSON.parse(jsonStr);
    console.log('最新进度:', latestData.hello);
    // 直接更新Vue组件的进度条状态
    component.progress = latestData.hello;
  } catch (error) {
    console.error('解析推送数据失败:', error);
  }
}

方法2:使用原生EventSource API(更推荐)

EventSource是浏览器原生支持SSE的API,会自动逐条接收推送,无需处理全量历史数据,代码更简洁:

static async synchronize(component: Vue) {
  // 注意:部分浏览器可能不支持EventSource设置PATCH方法,需提前确认兼容性
  const eventSource = new EventSource('myUrl.com', {
    headers: {
      'Authorization': 'mySessionToken',
      'Content-Type': 'text/event-stream'
    },
    method: 'PATCH'
  });

  // 接收每条推送
  eventSource.onmessage = function(event) {
    try {
      // 修正单引号为双引号后解析
      const latestData = JSON.parse(event.data.replace(/'/g, '"'));
      console.log('最新进度:', latestData.hello);
      // 更新组件进度
      component.progress = latestData.hello;

      // 进度到100时关闭连接
      if (latestData.hello === '100') {
        eventSource.close();
      }
    } catch (error) {
      console.error('解析推送数据失败:', error);
    }
  };

  // 处理连接错误
  eventSource.onerror = function(error) {
    console.error('SSE连接错误:', error);
    eventSource.close();
    // 触发错误回调逻辑
    // reject({status: error.status, statusText: error.message});
  };
}

内容的提问来源于stack exchange,提问作者user17196717

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:10:37