Ответ Нелека - лучший, опубликованный до сих пор, но он основан на установке значения css: white-space: pre, что может быть нежелательно.
Я хотел бы предложить другое решение, котороепытается решить реальный вопрос, который должен был быть задан здесь:
«Как вставить ненадежный текст в элемент DOM?»
Если вы доверяете тексту, почему бы просто не использовать innerHTML?
domElement.innerHTML = trustedText.replace(/\r/g, '').replace(/\n/g, '<br>');
должно быть достаточно для всех разумных случаев.
Если вы решили, что следует использовать .textContent вместо .innerHTML, это означает, что вы не доверяете тексту, которому высобирается вставить, верно?Это разумная проблема.
Например, у вас есть форма, в которой пользователь может создать сообщение, и после публикации текст сообщения сохраняется в вашей базе данных, а затем добавляется на страницы всякий раз, когда другие пользователипосетите соответствующую страницу.
Если вы используете здесь innerHTML, вы получите брешь в безопасности.то есть пользователь может публиковать что-то вроде
[script]alert(1);[/script]
(попробуйте представить, что [] являются <>, очевидно, переполнение стека добавляет текст небезопасным способом!)
, который не сработаетпредупреждение, если вы используете innerHTML, но оно должно дать вам представление о том, почему использование innerHTML может иметь проблемы.более умный пользователь будет публиковать
[img src="invalid_src" onerror="alert(1)"]
, что вызовет оповещение для каждого другого пользователя, который посещает страницу.Теперь у нас есть проблема.Даже более умный пользователь установит отображение: ни один в этом стиле img и заставит публиковать файлы cookie текущего пользователя на междоменном сайте.Поздравляем, все ваши данные для входа в систему теперь доступны в Интернете.
Итак, важно понять, что использование innerHTML не является неправильным, оно идеально, если вы просто используете его для создания шаблонов, используя толькоВаш собственный доверенный код разработчика.Реальный вопрос должен был звучать так: «Как добавить ненадежный пользовательский текст с новыми строками в мой HTML-документ».
Возникает вопрос: какую стратегию мы используем для новых строк?мы используем элементы [br]?[p] s или [div] s?
Вот короткая функция, которая решает проблему:
function insertUntrustedText(domElement, untrustedText, newlineStrategy) {
domElement.innerHTML = '';
var lines = untrustedText.replace(/\r/g, '').split('\n');
var linesLength = lines.length;
if(newlineStrategy === 'br') {
for(var i = 0; i < linesLength; i++) {
domElement.appendChild(document.createTextNode(lines[i]));
domElement.appendChild(document.createElement('br'));
}
}
else {
for(var i = 0; i < linesLength; i++) {
var lineElement = document.createElement(newlineStrategy);
lineElement.textContent = lines[i];
domElement.appendChild(lineElement);
}
}
}
Вы можете просто бросить это где-нибудь в вашем файле common_functions.js, а затем простозапускать и забывать всякий раз, когда вам нужно добавить какой-либо пользователь / api / etc -> ненадежный текст (т.е. не написанный вашей собственной командой разработчиков) на ваши html-страницы.
пример использования:
insertUntrustedText(document.querySelector('.myTextParent'), 'line1\nline2\r\nline3', 'br');
параметр newlineStrategy принимает только допустимые теги элементов dom, поэтому, если вы хотите [br] новые строки, передайте 'br', если вы хотите каждую строку в элементе [p], передайте 'p' и т. Д.