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

如何为流式返回的Claude API响应实时应用HTML与CSS样式?

解决方案:流式传输Claude响应时实时加样式且不暴露HTML标签

针对你的场景,最优方案是用Markdown替代直接输出HTML,结合前端实时解析渲染,既避免用户看到未闭合的标签,又能通过样式美化内容。以下是具体实现步骤:

一、先从Prompt层面规范输出

在调用Claude API的Prompt中明确要求输出Markdown格式,不要用HTML标签:

请使用标准Markdown格式输出内容,无需使用任何HTML标签。

这能从源头避免HTML标签的生成,简化后续处理。

二、前端改造(核心实现)

1. 安装依赖

引入轻量的Markdown解析库和XSS防护库:

npm install marked dompurify

2. 修改脚本逻辑

将原有的直接拼接文本改为存储Markdown内容,通过计算属性实时转成安全的HTML:

import { marked } from 'marked';
import DOMPurify from 'dompurify';
import { ref, computed, onBeforeUnmount } from 'vue';

const stillWriting = ref(false);
const eventSource = ref(null);
const allMessagesMarkdown = ref(''); // 存储原始Markdown内容

// 实时将Markdown转为安全HTML
const allMessages = computed(() => {
  // 解析Markdown为HTML
  let html = marked(allMessagesMarkdown.value);
  // 过滤XSS风险内容
  return DOMPurify.sanitize(html);
});

function triggerStreaming(url) {
  stillWriting.value = true;
  allMessagesMarkdown.value = '';
  eventSource.value = new EventSource(url);

  eventSource.value.addEventListener("update", (event) => {
    if (event.data === "<END_STREAMING_SSE>") {
      eventSource.value.close();
      stillWriting.value = false;
      return;
    }

    const data = JSON.parse(event.data);
    if (data.text) {
      // 拼接Markdown内容,而非直接拼接HTML
      allMessagesMarkdown.value += data.text;
    }
  });

  eventSource.value.addEventListener("error", (event) => {
    allMessagesMarkdown.value += '\n\n⚠️ 发生错误,请稍后重试。';
    eventSource.value?.close();
    stillWriting.value = false;
  });
}

onBeforeUnmount(() => {
  eventSource.value?.close();
});

3. 配置Tailwind样式

给Markdown渲染后的HTML元素添加Tailwind样式,在项目的全局CSS或组件样式中添加:

.chat-messages h1 {
  @apply text-2xl font-bold mt-4 mb-2;
}
.chat-messages h2 {
  @apply text-xl font-bold mt-3 mb-1;
}
.chat-messages p {
  @apply mb-2 leading-relaxed;
}
.chat-messages strong {
  @apply font-bold text-gray-800;
}
.chat-messages em {
  @apply italic text-gray-700;
}
.chat-messages code {
  @apply bg-gray-100 px-1 py-0.5 rounded font-mono text-sm;
}
.chat-messages pre {
  @apply bg-gray-100 p-3 rounded overflow-x-auto my-2;
}
.chat-messages ul, .chat-messages ol {
  @apply pl-5 mb-2;
}
.chat-messages li {
  @apply mb-1;
}
.chat-messages blockquote {
  @apply border-l-4 border-blue-200 pl-3 italic text-gray-600 my-2;
}

三、为什么这个方案可行?

  1. 避免标签暴露:Markdown语法即使是分块传输(比如先收到**加粗,后收到内容**),解析后的中间状态只会显示普通文本,不会出现未闭合的HTML标签。
  2. 实时渲染样式:计算属性会随着Markdown内容的更新自动重新解析渲染,保持流式体验。
  3. 安全可靠:通过DOMPurify过滤XSS风险,避免恶意内容注入。

备选:如果必须用HTML输出

如果因为特殊需求需要Claude输出HTML,需要后端配合确保每个分块发送完整的HTML标签:

  • 后端缓存未闭合的标签(比如<b>),在下一个分块中补充完整的内容和闭合标签(内容</b>)后再发送。
  • 前端依然用v-html渲染,但这种方式复杂度高,容易出现样式错乱,不推荐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 08:55:56