Рассмотрим этот простой код ниже
Когда я анализирую контент и получаю «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-кода в том виде, в каком он есть, потому что он всегда будет отображать его. Попробуйте InnerText или InnerContent; см. документацию... Developer.mozilla.org/en-US/docs/Web/API/Node/textContent
@GetSet Я думаю, что OP хочет отображать это как HTML, а не как текст.
Я думаю, возможно, мне придется продолжать добавлять к скрытому div, используя Innerhtml, а затем использовать InsertAdjacentHTML с этим содержимым? угу... но это повлияет на потоковую передачу. Я в замешательстве
Судя по комментариям из ответа, вы хотите повторить то, что делает ChatGPT? То есть - визуализировать на стороне сервера сообщение, которое может содержать фрагменты кода, отправить его во внешний интерфейс и отобразить его в качестве ответа? Если это так, рассматривали ли вы, например, использование htmlentities(...) в вашем send-message.php для тех фрагментов, которые вы не хотите видеть в формате HTML, а затем вставку этого в свой document.getElementById(uuid) с помощью innerHTML? Идея состоит в том, чтобы выполнить всю подготовку внутри server-message.php и использовать интерфейс только для его отображения.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете добавить свой 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 Я понимаю. Но согласны ли мы, что в моем примере это работает? Потому что, если мы с этим согласны, то следующая мысль будет заключаться в том, что хорошо, это работает для меня, но не работает для вашего примера, поэтому между вашим примером и моим должна быть разница, из-за которой ваш не работает должным образом. Следовательно, вам нужно создать фрагмент, чтобы мы могли воспроизвести эту проблему.
Спасибо . На самом деле мои фрагменты кода основаны на github.com/orhanerday/ChatGPT. Потоковый ответ от ChatGpt содержит HTML-коды как часть приглашения/настроек и т. д. надеюсь, это поможет
@sdavRaj, если вы создадите воспроизводимый пример в виде фрагмента вашего вопроса, то я буду рад изучить его и попробовать. Дайте мне знать, когда вы добавите фрагмент к своему вопросу.
Я пытался заставить openAi использовать HTML-уценку вместо стандартной уценки при потоковой передаче ответа. Не идеально, так как можно попробовать внедрить HTML. Спорно (если серверный источник является надежным и проверенным и нет CORS, это не проблема, кстати).
Кроме того, с потоковой передачей HTML дела пошли наперекосяк.
Итак, я решил не использовать HTML в потоковом ответе, а использовать стандартную уценку OpenAi.
И я просто применяю уценку после завершения потока, а не к частям, и все работает нормально. Пользователю это кажется немного странным, поскольку формат внезапно меняется... но эй... должно быть все в порядке.
Решение в с использованием Showdown JS с потоковым ответом OpenAi
.innerHTMLотобразит строку с тегами HTML как HTML. Возможно, проверьте, что на самом деле содержитtxt, зарегистрировав это (возможно, оно содержит HTML-объекты, которые требуют анализа, поэтому вы видите теги в виде текста)