vue2接收流式接口返回的数据

1、Nginx 代理需要关闭缓存机制

2、前端用fetch接收(我用的),还可以用其他的方式去接收

  methods: {
    getContent() {
      let parmas = {};
      const controller = new AbortController();
      const { signal } = controller;
      fetch("你的url", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify(parmas),
        signal
      })
        .then(async response => {
          if (!response.body) {
            throw new Error("No response body received from server.");
          }

          // 流形式数据,只允许解析一遍,get过后就没了,所以务必不要多次解析!!!
          const reader = response.body.getReader();
          if (!reader) {
            throw new Error("Failed to obtain reader from response body.");
          }

          const decoder = new TextDecoder("utf-8");
          let isDone = false;
          let buffer = ``; // 用于存储和解析 SSE 数据
          while (!isDone) {
            try {
              if (!reader || !response.body) {
                break;
              }
              const { done, value } = await reader.read();
              isDone = done;
              if (done) {
                break; // 退出循环
              }
              if (!value) {
                continue;
              }
              const decodedText = decoder.decode(value, { stream: true });
              buffer += decodedText;
              let parts = buffer.split("\n\n");
              buffer = parts.pop();
              parts.forEach(part => {
                try {
                  if (this.processChunk(part.trim())) {
                    isDone = true;
                  }
                } catch (error) {
                  throw error;
                }
              });
            } catch (readError) {
              throw readError;
            }
          }
          if (buffer && !isDone) {
            // 仅当流未结束时处理 buffer
            try {
              if (this.processChunk(buffer)) {
                isDone = true;
              }
            } catch (error) {
              throw error;
            }
          }
          if (isDone) {
            controller.abort();
          }
        })
        .catch(err => {
          console.log("message", err);
          controller.abort();
        });
    },
    processChunk(chunk) {
      let messages = chunk.split("data: ");
      for (let message of messages) {
        if (message.endsWith("data:[DONE]")) {
          message = message.split("data:[DONE]")[0];
        }
        if (message) {
          const parsedMessage = JSON.parse(message);
          let { id = "" } = parsedMessage;
          this.conversationId = id;
          if (parsedMessage.choices && parsedMessage.choices.length > 0) {
            const delta = parsedMessage.choices[0].delta;
            if (delta.content) {
              this.content =+ delta.content;
            }
          }
        }
      }
    }
  }

注意:片段会有接收不全的情况,需要拼接成一个整的再去渲染到页面上,成功后控制台显示多条记录。

### Vue2接收后端流式输出的实现方法 在 Vue2 中处理后端返回流式数据,通常涉及以下几个方面:配置 HTTP 请求以支持流式响应、逐步读取服务器发送的数据以及实时更新界面。以下是具体的实现方式。 #### 配置 Axios 支持流式请求 Axios 是一种常用的 HTTP 客户端库,在 Vue 项目中广泛使用。要处理流式数据,可以通过 `responseType` 设置为 `'stream'` 或其他适合的形式来启用流式传输功能[^1]。 ```javascript const axiosInstance = axios.create({ responseType: 'stream', // 设置响应类型为流 }); ``` 通过上述配置,可以确保 Axios 能够正确解析来自后端的流式数据。 #### 处理流式数据并实现实时更新 当接收流式数据时,前端需要监听事件并对每次传入的内容进行操作。以下是一个基于 Axios 的示例代码: ```javascript axios.get('/api/stream-endpoint', { responseType: 'stream' }) .then(response => { const reader = response.data.body.getReader(); // 获取可读流对象 let resultText = ''; function readStream() { return reader.read().then(({ done, value }) => { if (done) { console.log('流已结束'); return; } const chunk = new TextDecoder('utf-8').decode(value); // 解码二进制数据 resultText += chunk; // 更新到页面上(例如模拟打字效果) document.getElementById('output').textContent += chunk; return readStream(); }); } readStream(); }).catch(error => { console.error('发生错误:', error); }); ``` 此代码片段展示了如何利用浏览器内置的 Readable Streams API 来逐块读取消息,并将其解码成字符串形式显示给用户。 对于某些场景下可能还需要考虑性能优化问题,比如限制每秒渲染次数或者批量追加文本而不是频繁修改 DOM 结构等措施都可以提升用户体验。 #### 文件下载中的应用实例 如果目标是从后端获取大文件并通过 vue 应用提供给用户作为附件保存,则需注意调整 headers 和 content-disposition 属性以便指示浏览器执行下载动作而非直接展示内容[^2]。下面给出一段简单的例子用于说明这一过程: ```javascript function downloadFile(url){ fetch(url,{ method:"GET", credentials:'include', mode:'cors' }).then(res=>{ if(!res.ok){ throw new Error(`HTTP 错误! 状态码:${res.status}`); } const contentType=res.headers.get("content-type"); const filename=getFileNameFromHeader(res.headers); res.blob().then(blob=>createDownloadLink(blob,filename)); }); } // 辅助函数定义省略... ``` 以上脚本实现了从指定 URL 地址拉取资源并将之转换成本地可用链接供点击触发实际存储行为的功能。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值