将解析后的 JSON 视为 HTML 而不是文本(已编辑)

问题描述 投票:0回答:1

考虑下面这个简单的代码

当我解析内容并使用

JSON.parse(e.data).choices[0].delta.content;
获取“txt”时,如果它是纯文本,它就可以正常工作。但是,响应中有一些简单的 HTML 标记,如
<strong>
等,它们不会在浏览器中呈现为 HTML。

我不知道如何按原样渲染它。我意识到数据块到达时可能没有结束 HTML 标签,也可能有不完整的 HTML 标签,但是当流结束时,通常一切都会好起来。

如何确保浏览器将“txt”内容视为 HTML 而不是文本?变量 thisWebPath 设置得很好,并且确实以 JSON 形式返回流数据

提前致谢

function sendMsg(msg) {

    var formData = new FormData();
    formData.append('msg', msg);
    formData.append('user_id', USER_ID);
    fetch(thisWebPath + '/send-message.php', {method: 'POST', body: formData})
        .then(response => response.json())
        .then(data => {
            let uuid = uuidv4()
            const eventSource = new EventSource(thisWebPath + `/event-stream.php?chat_history_id=${data.id}&id=${encodeURIComponent(USER_ID)}`);
            appendMessage(BOT_NAME, BOT_IMG, "left", "", uuid);
            const div = document.getElementById(uuid);

            eventSource.onmessage = function (e) {
                if (e.data == "[DONE]") {
                    msgerSendBtn.disabled = false;
                    document.getElementById("userSendButtonAV").value="Send";
                    var elemB = document.getElementById("userSendButtonAV");
                    elemB.value = "Send";


                    document.getElementById('userMessageAV').placeholder='Enter your message now...';
                    document.getElementById('userMessageAV').disabled = false;
                

                    eventSource.close();
                } else {
                    
                    //original code  let txt = JSON.parse(e.data).choices[0].delta.content
                    if (isJsonString(e.data)) {
                        let txt = JSON.parse(e.data).choices[0].delta.content;

                    if (txt !== undefined) {
                        div.innerHTML += txt.replace(/(?:\r\n|\r|\n)/g, '<br>');
                    }
                } 
                        
            }
            };
            eventSource.onerror = function (e) {

                var elemC = document.getElementById("userSendButtonAV");
                elemC.value = "Send";

                
                msgerSendBtn.disabled = false;
                document.getElementById('userMessageAV').placeholder='Enter your message now...';
                document.getElementById('userMessageAV').disabled = false;
            
                //console.log(e);
                eventSource.close();
            };
        })
        .catch(error => console.error(error));


}

我希望像 HTML 一样处理文本

编辑:这就是我当前添加消息的方式


function appendMessage(name, img, side, text, id) {
    //   Simple solution for small apps
    const msgHTML = `
    <div class="msg ${side}-msg">
      <!--- div class="msg-img" style="background-image: url(${img})"></div --->
      <div class="msg-bubble">
        <div class="msg-info">
          <div class="msg-info-name">${name}</div>
          <div class="msg-info-time">${formatDate(new Date())}</div>
        </div>

        <div class="msg-text" id=${id}>${text}</div>
      </div>
    </div>
  `;

    if ( typeof(text) !== "undefined" && text !== null )  {
        msgerChat.insertAdjacentHTML("beforeend", msgHTML);
        msgerChat.scrollTop += 500;
    }
}

insertAdjacentText is a function, but that is even worse... it just writes out the entire text including the html code

再次编辑:

整个新的 div 进入主标签,例如

    <main class="msger-chat">
    </main>

甚至是动态生成的,以及一堆其他东西,这就是使用 insertAdjacentHtml 的原因

我如何简单地使用innerHtml附加内容,以便将以以下内容开头的新div添加到“主”元素的末尾?

 <div class="msg ${side}-msg">

又一个编辑。问题是 text/event-stream 内容类型,所以显然浏览器将其视为文本:-(我在 chrome 中看到了检查网络

即使我为其添加utf-8后缀,浏览器仍然将其视为文本而不是html。 我认为这是主要问题....

javascript json stream fetch-api
1个回答
0
投票

您可以通过

innerHTML
运算符将 HTML 附加到
+=
,它将被评估为 HTML:

function getTemplate() {
    return "<p style='background-color: green;'>something</p>";
}

function addTemplate(div) {
    let txt = getTemplate();
    div.innerHTML += txt;
}
<div id="foo"></div>
<input type="button" onclick="addTemplate(document.getElementById('foo'))"  value="add">

如果您没有遇到这种情况,那么您需要提供一个片段,我们可以在其中重现它。

© www.soinside.com 2019 - 2024. All rights reserved.