Обрабатывать разобранный JSON как HTML, а не как текст (отредактировано)

Рассмотрим этот простой код ниже

Когда я анализирую контент и получаю «txt» с помощью JSON.parse(e.data).choices[0].delta.content;, тогда все работает нормально, если это обычный текст. Однако в ответе есть несколько простых 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.info(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">

Еще одно редактирование. Проблема заключается в типе контента «текст/поток событий», поэтому, очевидно, браузер обрабатывает его как текст :-( Я видел сеть проверки в Chrome

Даже если я добавлю к нему суффикс utf-8, браузер все равно будет воспринимать его как текст, а не как HTML. Я думаю это главный вопрос....

.innerHTML отобразит строку с тегами HTML как HTML. Возможно, проверьте, что на самом деле содержит txt, зарегистрировав это (возможно, оно содержит HTML-объекты, которые требуют анализа, поэтому вы видите теги в виде текста)
Nick Parsons 24.02.2024 12:00

Не используйте InnerHTML для отображения HTML-кода в том виде, в каком он есть, потому что он всегда будет отображать его. Попробуйте InnerText или InnerContent; см. документацию... Developer.mozilla.org/en-US/docs/Web/API/Node/textContent

GetSet 24.02.2024 12:00

@GetSet Я думаю, что OP хочет отображать это как HTML, а не как текст.

Nick Parsons 24.02.2024 12:03

Я думаю, возможно, мне придется продолжать добавлять к скрытому div, используя Innerhtml, а затем использовать InsertAdjacentHTML с этим содержимым? угу... но это повлияет на потоковую передачу. Я в замешательстве

sdavRaj 24.02.2024 12:50

Судя по комментариям из ответа, вы хотите повторить то, что делает ChatGPT? То есть - визуализировать на стороне сервера сообщение, которое может содержать фрагменты кода, отправить его во внешний интерфейс и отобразить его в качестве ответа? Если это так, рассматривали ли вы, например, использование htmlentities(...) в вашем send-message.php для тех фрагментов, которые вы не хотите видеть в формате HTML, а затем вставку этого в свой document.getElementById(uuid) с помощью innerHTML? Идея состоит в том, чтобы выполнить всю подготовку внутри server-message.php и использовать интерфейс только для его отображения.

FiddlingAway 25.02.2024 12:54
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
5
104
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете добавить свой HTML к innerHTML с помощью оператора +=, и он будет оценен как 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">

Если с вами этого не происходит, вам нужно будет предоставить фрагмент, где мы сможем это воспроизвести.

Нет... не сработало. Фактически, я также добавил свой собственный HTML в «txt», а затем добавил в div, используя внутренний HTML, но только мой код в HTML отображался как HTML, а остальное как обычно.

sdavRaj 24.02.2024 20:22

@sdavRaj Я понимаю. Но согласны ли мы, что в моем примере это работает? Потому что, если мы с этим согласны, то следующая мысль будет заключаться в том, что хорошо, это работает для меня, но не работает для вашего примера, поэтому между вашим примером и моим должна быть разница, из-за которой ваш не работает должным образом. Следовательно, вам нужно создать фрагмент, чтобы мы могли воспроизвести эту проблему.

Lajos Arpad 24.02.2024 21:05

Спасибо . На самом деле мои фрагменты кода основаны на github.com/orhanerday/ChatGPT. Потоковый ответ от ChatGpt содержит HTML-коды как часть приглашения/настроек и т. д. надеюсь, это поможет

sdavRaj 25.02.2024 08:49

@sdavRaj, если вы создадите воспроизводимый пример в виде фрагмента вашего вопроса, то я буду рад изучить его и попробовать. Дайте мне знать, когда вы добавите фрагмент к своему вопросу.

Lajos Arpad 25.02.2024 12:31

Я пытался заставить openAi использовать HTML-уценку вместо стандартной уценки при потоковой передаче ответа. Не идеально, так как можно попробовать внедрить HTML. Спорно (если серверный источник является надежным и проверенным и нет CORS, это не проблема, кстати).

Кроме того, с потоковой передачей HTML дела пошли наперекосяк.

Итак, я решил не использовать HTML в потоковом ответе, а использовать стандартную уценку OpenAi.

И я просто применяю уценку после завершения потока, а не к частям, и все работает нормально. Пользователю это кажется немного странным, поскольку формат внезапно меняется... но эй... должно быть все в порядке.

Решение в с использованием Showdown JS с потоковым ответом OpenAi

Другие вопросы по теме