当前位置: 首页 > news >正文

前端实现流式输出《后端返回Markdown格式文本,前端输出类似于打字的那种》

一、使用插件

插件名称:marked
版本:15.0.11
安装插件:npm install marked@15.0.11
作用:marked 是一个用于将 Markdown 语法转换为 HTML 的 JavaScript 库

插件2名称:dompurify
版本:3.2.5
安装插件:npm install dompurify@3.2.5
作用:DOMPurify 是一个专门用于防止 XSS(跨站脚本攻击)的快速、易用且强大的工具。

二、代码实现

  <div v-html="MdHtml"></div>import { marked } from 'marked'import DOMPurify from 'dompurify'// 推荐使用fetch function Fetch({ url, method, data }) {return new Promise(async (resolve, reject) => {window.controller = new AbortController();let sig = window.controller.signal;try {var response = await fetch(url, {headers: {'Authorization': 'Bearer ' + gettoken(),'Content-Type': 'application/json'},method: method,body: JSON.stringify(data),signal:sig })if (response.status != 200) {reject(response)} else {resolve(response)}} catch (err) {reject(err)}})
}
const MdHtml = ref('')
// 发送网络请求
const API = async () => {let param = {"id": 'xxx',}let outText = '' // 用于存储所有接收到的数据块的文本。Fetch({url: `/xxx/xxx/xxx`,method: 'post',data: param}).then(async res => {// res.body 是一个可读的流const reader = res.body.getReader() // getReader 方法返回一个读取器(ReadableStreamDefaultReader),用于读取流中的数据块const dec = new TextDecoder() //  用于将二进制数据解码为文本(解码当前数据块)while (true) {/*** reader.read() 返回一个 Promise,解析为一个对象,包含 done 和 value。* done 表示流是否已经结束。* value 是当前数据块的二进制数据。* 如果 done 为 true,表示流已经结束,调用 getComparsonHistoryNet() 并退出循环*/const { done, value } = await reader.read()if (done) { // 结束后调用别的函数break}const ck = dec.decode(value, { stream: true }) // stream: true 表示这是一个流式解码,适用于部分数据。outText += ck// 解码后的文本块添加到 outText 中const outHtml = marked.parse(outText) // 使用 marked 库将 outText 转换为 HTMLMdHtml.value = DOMPurify.sanitize(outHtml) //使用 DOMPurify 库对生成的 HTML 进行安全处理,防止 XSS 攻击 (将处理后的 HTML 赋值给 MdHtml.value,通常用于更新 Vue 组件的响应式数据)};onMounted(() => {API()
})

三、为什么用 fetch 但是不用 axios
在前端实现流式输出(例如处理服务器发送的事件流,如 SSE 或者分块传输的响应),fetch API 相比 axios 更受推荐的原因主要在于其对流式数据处理的原生支持以及更灵活的控制能力。以下是具体原因:

1. 原生支持流处理
fetch 提供了对 ReadableStream 的直接支持,允许你通过 .body 属性访问响应体作为一个可读流。这意味着你可以逐块读取数据,并且可以在数据到达时立即开始处理,而不是等待整个响应完成。

fetch('your-stream-endpoint').then(response => {const reader = response.body.getReader();const decoder = new TextDecoder('utf-8');function read() {reader.read().then(({ done, value }) => {if (done) {console.log('Stream complete');return;}console.log(decoder.decode(value, { stream: true }));read(); // Continue reading});}read();});

axios 默认情况下不支持流式处理,尽管可以通过配置 responseType: ‘stream’ 来尝试获取流数据,但这通常仅限于 Node.js 环境下使用,并且对于浏览器端的支持不如 fetch 自然和直接。

四、总结
当涉及到流式数据处理时,fetch 因为其对 ReadableStream 的原生支持、更轻量的特点以及更高的灵活性,成为了更优的选择。然而,这并不意味着 axios 不好,它在很多其他场景下仍然是一个强大的 HTTP 客户端工具,尤其是在需要高级功能如请求/响应拦截、自动转换 JSON 数据等方面表现突出。选择哪个工具应基于具体的项目需求来决定。如果项目中大量使用了 axios 并且对流式处理的需求不多,可能继续使用 axios 加上适当的扩展也是可行的。但如果主要是为了处理流式数据,那么 fetch 将是更好的选择。

相关文章:

  • Systemd基础
  • qtc++ qdebug日志生成
  • 【gRPC】HTTP/2协议,HTTP/1.x中线头阻塞问题由来,及HTTP/2中的解决方案,RPC、Protobuf、HTTP/2 的关系及核心知识点汇总
  • 项目QT+ffmpeg+rtsp(一)——Qt的安装和rtsp的测试
  • python中集合的操作
  • Python 中的 typing.ClassVar 详解
  • 会议分享|高超声速流动测量技术研讨会精彩探析
  • windows下authas调试tomcat
  • 青少年ctf平台应急响应-应急响应1
  • 基于 nvitop+Prometheus+Grafana 的物理资源与 VLLM 引擎服务监控方案
  • 自学嵌入式 day19-数据结构 链表
  • 二水平设计的单次重复
  • 阳台光伏+储能:安科瑞智能计量仪表来助力
  • 学习海康VisionMaster之直方图工具
  • uniapp+vue3页面滚动加载数据
  • 现代计算机图形学Games101入门笔记(十四)
  • 电磁兼容性优化设计在汽车电子芯片中的实践
  • 在 VSCode 中运行 Vue.js 项目
  • 动态范围调整(SEF算法实现)
  • 不清楚的点
  • 沃尔玛上财季净利下滑12%:关税带来成本压力,新财季价格涨幅将高于去年
  • 中国情怀:时代记录与家国镜相|澎湃·镜相第三届非虚构写作大赛征稿启事
  • 河南信阳:对违规吃喝问题不遮丑不护短,露头就打、反复敲打
  • 体坛联播|巴萨提前2轮西甲夺冠,郑钦文不敌高芙止步4强
  • 玉渊谭天丨卢拉谈美国降低对华关税:中国的行动捍卫了主权
  • 上海市国防动员办公室副主任吴斌接受审查调查