Eu quero exibir um texto em HTML por uma função javascript. Como posso escapar caracteres especiais html em JS? Existe uma API?
Eu quero exibir um texto em HTML por uma função javascript. Como posso escapar caracteres especiais html em JS? Existe uma API?
Respostas:
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
replace()chamadas são desnecessárias. Seqüências de caracteres simples de caracteres antigos simples também serviriam.
function escapeHtml(html){
var text = document.createTextNode(html);
var p = document.createElement('p');
p.appendChild(text);
return p.innerHTML;
}
// Escape while typing & print result
document.querySelector('input').addEventListener('input', e => {
console.clear();
console.log( escapeHtml(e.target.value) );
});
<input style='width:90%; padding:6px;' placeholder='<b>cool</b>'>
Você pode usar a .text()função do jQuery .
Por exemplo:
Na documentação do jQuery referente à .text()função:
Precisamos estar cientes de que esse método escapa à string fornecida conforme necessário para que seja renderizada corretamente em HTML. Para fazer isso, ele chama o método DOM .createTextNode (), não interpreta a sequência como HTML.
As versões anteriores da documentação do jQuery escreveram da seguinte maneira ( ênfase adicionada ):
Precisamos estar cientes de que esse método escapa à string fornecida conforme necessário para que seja renderizada corretamente em HTML. Para fazer isso, ele chama o método DOM .createTextNode (), que substitui caracteres especiais pelos seus equivalentes de entidade HTML (como & lt; for <).
const str = "foo<>'\"&"; $('<div>').text(str).html()rendimentosfoo<>'"&
Acho que encontrei a maneira correta de fazer isso ...
// Create a DOM Text node:
var text_node = document.createTextNode(unescaped_text);
// Get the HTML element where you want to insert the text into:
var elem = document.getElementById('msg_span');
// Optional: clear its old contents
//elem.innerHTML = '';
// Append the text node into it:
elem.appendChild(text_node);
document.createTextNode("<script>alert('Attack!')</script>").textContent
Esta é, de longe, a maneira mais rápida que eu já vi. Além disso, ele faz tudo sem adicionar, remover ou alterar elementos na página.
function escapeHTML(unsafeText) {
let div = document.createElement('div');
div.innerText = unsafeText;
return div.innerHTML;
}
var divCode = '<div data-title="' + escapeHTML('Jerry "Bull" Winston') + '">Div content</div>', produzirá HTML inválido!
Foi interessante encontrar uma solução melhor:
var escapeHTML = function(unsafe) {
return unsafe.replace(/[&<"']/g, function(m) {
switch (m) {
case '&':
return '&';
case '<':
return '<';
case '"':
return '"';
default:
return ''';
}
});
};
Não analiso >porque não quebra o código XML / HTML no resultado.
Aqui estão os benchmarks: http://jsperf.com/regexpairs
Além disso, criei uma escapefunção universal : http://jsperf.com/regexpairs2
A maneira mais concisa e com melhor desempenho de exibir texto não codificado é usar textContentproperty.
Mais rápido que usar innerHTML. E isso sem levar em conta escapar de sobrecarga.
document.body.textContent = 'a <b> c </b>';
</seja atendida.
Os elementos DOM suportam a conversão de texto em HTML, atribuindo a innerText . innerText não é uma função, mas atribuir a ela funciona como se o texto tivesse escapado.
document.querySelectorAll('#id')[0].innerText = 'unsafe " String >><>';
<br>de múltiplas linhas adiciona elementos no lugar de novas linhas, que podem quebrar certos elementos, como estilos ou scripts. O createTextNodenão é propenso a esse problema.
innerTexttem alguns problemas de legado / especificação. Melhor usar textContent.
Você pode codificar todos os caracteres da sua string:
function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
Ou apenas alveje os personagens principais com os quais se preocupar (&, inebreaks, <,>, "e ') como:
function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}
test.value=encode('How to encode\nonly html tags &<>\'" nice & fast!');
/*************
* \x26 is &ersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55">www.WHAK.com</textarea>
Uma linha (para ES6 +):
var escapeHtml = s => (s + '').replace(/[&<>"']/g, m => ({
'&': '&', '<': '<', '>': '>',
'"': '"', "'": '''
})[m]);
Para versões mais antigas:
function escapeHtml(s) {
return (s + '').replace(/[&<>"']/g, function (m) {
return ({
'&': '&', '<': '<', '>': '>',
'"': '"', "'": '''
})[m];
});
}
Me deparei com esse problema ao criar uma estrutura DOM. Esta pergunta me ajudou a resolvê-lo. Eu queria usar uma divisa dupla como separador de caminho, mas o acréscimo de um novo nó de texto resultou diretamente na exibição do código de caractere de escape, em vez do próprio caractere:
var _div = document.createElement('div');
var _separator = document.createTextNode('»');
//_div.appendChild(_separator); /* this resulted in '»' being displayed */
_div.innerHTML = _separator.textContent; /* this was key */
Se você já usa módulos no seu aplicativo, pode usar o módulo escape-html .
import escapeHtml from 'escape-html';
const unsafeString = '<script>alert("XSS");</script>';
const safeString = escapeHtml(unsafeString);
Eu vim com esta solução.
Vamos supor que queremos adicionar algum html ao elemento com dados não seguros do usuário ou banco de dados.
var unsafe = 'some unsafe data like <script>alert("oops");</script> here';
var html = '';
html += '<div>';
html += '<p>' + unsafe + '</p>';
html += '</div>';
element.html(html);
Não é seguro contra ataques XSS. Agora adicione isso.
$(document.createElement('div')).html(unsafe).text();
Então é
var unsafe = 'some unsafe data like <script>alert("oops");</script> here';
var html = '';
html += '<div>';
html += '<p>' + $(document.createElement('div')).html(unsafe).text(); + '</p>';
html += '</div>';
element.html(html);
Para mim, isso é muito mais fácil do que usar .replace()e será removido !!! todas as tags html possíveis (espero).
<script>em <script>.