Jawaban:
Catatan keamanan: menggunakan jawaban ini (disimpan dalam bentuk aslinya di bawah) dapat memperkenalkan kerentanan XSS ke dalam aplikasi Anda. Anda sebaiknya tidak menggunakan jawaban ini. Baca jawaban lucascaro untuk penjelasan tentang kerentanan dalam jawaban ini, dan gunakan pendekatan dari jawaban itu atau bukan jawaban Mark Amery .
Sebenarnya, cobalah
var decoded = $("<div/>").html(encodedStr).text();
$("<div/>").html('<img src="http://www.google.com/images/logos/ps_logo2.png" onload=alert(1337)>')
. Di Firefox atau Safari, ia mengaktifkan peringatan.
str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/g, "")
atau yang serupa.
Tanpa jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
Ini bekerja mirip dengan jawaban yang diterima , tetapi aman untuk digunakan dengan input pengguna yang tidak dipercaya.
Seperti dicatat oleh Mike Samuel , melakukan ini dengan <div>
bukan <textarea>
dengan input pengguna yang tidak dipercaya adalah kerentanan XSS, bahkan jika <div>
itu tidak pernah ditambahkan ke DOM:
function decodeEntities(encodedString) {
var div = document.createElement('div');
div.innerHTML = encodedString;
return div.textContent;
}
// Shows an alert
decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">')
Namun, serangan ini tidak dimungkinkan terhadap a <textarea>
karena tidak ada elemen HTML yang diizinkan konten a<textarea>
. Akibatnya, setiap tag HTML yang masih ada dalam string 'disandikan' akan secara otomatis disandikan oleh browser.
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
// Safe, and returns the correct answer
console.log(decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">'))
Peringatan : Melakukan ini menggunakan jQuery's
.html()
dan.val()
metode alih-alih menggunakan.innerHTML
dan.value
juga tidak aman * untuk beberapa versi jQuery, bahkan ketika menggunakan atextarea
. Ini karena versi jQuery yang lebih lama akan secara sengaja dan eksplisit mengevaluasi skrip yang terkandung dalam string yang diteruskan ke.html()
. Karenanya kode seperti ini menunjukkan peringatan di jQuery 1.8:
//<!-- CDATA
// Shows alert
$("<textarea>")
.html("<script>alert(1337);</script>")
.text();
//-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
* Terima kasih kepada Eru Penkman karena telah menangkap kerentanan ini.
decodedString = textArea.value;
textArea.remove();
return decodedString;
if ('remove' in Element.prototype) textArea.remove();
$("<div />").html(string).text()
akan mengeksekusi semua javascript dalam string yang disediakan , yang saya duga adalah penyebab masalah Anda. Jawaban yang diterima harus diperbarui untuk yang satu ini.
Seperti yang dikatakan Mike Samuel, jangan gunakan jQuery.html (). Text () untuk mendekode entitas html karena tidak aman.
Sebagai gantinya, gunakan perender template seperti Mustache.js atau decodeEntities dari komentar @ VyvIT.
Pustaka sabuk utilitas Underscore.js dilengkapi dengan escape
dan unescape
metode, tetapi tidak aman untuk input pengguna:
unescape
dalam dokumen sekarang, btw.
_.unescape("'")
menghasilkan hanya "& # 39;" bukannya kutipan tunggal. Apakah ada sesuatu yang saya lewatkan atau garis bawah tidak melarikan diri ke kode entitas HTML seperti yang ditunjukkan pada: w3schools.com/tags/ref_entities.asp
escape
dan unescape
metode Underscore ... tidak aman untuk input pengguna" . Apa yang Anda maksud dengan ini? Kedengarannya seperti omong kosong bagi saya, tapi mungkin saya kehilangan sesuatu - dapatkah Anda menjelaskannya?
_.unescape("<img src=fake onerror=alert('boo!')>")
(di Chrome / FF / IE). Tapi itu tidak muncul waspada. Mencoba di konsol dan juga memasukkannya ke dalam file JS saya. Hasil yang sama
Saya pikir Anda membingungkan metode teks dan HTML. Lihatlah contoh ini, jika Anda menggunakan HTML bagian dalam elemen sebagai teks, Anda akan mendapatkan tag HTML yang didekodekan (tombol kedua). Tetapi jika Anda menggunakannya sebagai HTML, Anda akan mendapatkan tampilan berformat HTML (tombol pertama).
<div id="myDiv">
here is a <b>HTML</b> content.
</div>
<br />
<input value="Write as HTML" type="button" onclick="javascript:$('#resultDiv').html($('#myDiv').html());" />
<input value="Write as Text" type="button" onclick="javascript:$('#resultDiv').text($('#myDiv').html());" />
<br /><br />
<div id="resultDiv">
Results here !
</div>
Tombol pertama menulis: di sini adalah konten HTML .
Tombol kedua menulis: di sini adalah konten <B> HTML </B>.
Omong-omong, Anda dapat melihat plug-in yang saya temukan di jQuery plugin - HTML decode dan encode yang mengkodekan dan mendekode string HTML.
Pertanyaannya dibatasi oleh 'with jQuery' tetapi mungkin membantu beberapa orang untuk mengetahui bahwa kode jQuery yang diberikan dalam jawaban terbaik di sini melakukan hal berikut di bawah ini ... ini berfungsi dengan atau tanpa jQuery:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
Anda dapat menggunakan perpustakaan he , tersedia dari https://github.com/mathiasbynens/he
Contoh:
console.log(he.decode("Jörg & Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
Saya menantang penulis perpustakaan tentang pertanyaan apakah ada alasan untuk menggunakan perpustakaan ini dalam kode sisi klien demi <textarea>
peretasan yang diberikan dalam jawaban lain di sini dan di tempat lain. Dia memberikan beberapa kemungkinan pembenaran:
Jika Anda menggunakan node.js serverside, menggunakan pustaka untuk pengkodean / decoding HTML memberi Anda solusi tunggal yang berfungsi baik di sisi klien dan di sisi server.
Algoritme penguraian entitas entitas peramban memiliki bug atau tidak ada dukungan untuk beberapa referensi karakter bernama . Sebagai contoh, Internet Explorer akan mendekode dan membuat spasi yang tidak melanggar (
) dengan benar tetapi melaporkannya sebagai ruang biasa alih-alih yang tidak melanggar melalui innerText
properti elemen DOM , memecahkan <textarea>
peretasan (meskipun hanya dengan sedikit cara). Selain itu, IE 8 dan 9 hanya tidak mendukung salah satu referensi karakter baru bernama ditambahkan dalam HTML 5. Penulis ia juga menjadi tuan tes bernama dukungan referensi karakter di http://mathias.html5.org/tests/html / bernama-karakter-referensi / . Di IE 8, ini melaporkan lebih dari seribu kesalahan.
Jika Anda ingin diisolasi dari bug peramban yang terkait dengan penguraian kode entitas dan / atau dapat menangani serangkaian referensi karakter bernama lengkap, Anda tidak bisa lolos dari <textarea>
peretasan; Anda akan membutuhkan perpustakaan seperti dia .
Dia hanya merasa sangat baik seperti melakukan hal-hal dengan cara seperti ini.
menyandi:
$("<textarea/>").html('<a>').html(); // return '<a>'
membaca sandi:
$("<textarea/>").html('<a>').val() // return '<a>'
Menggunakan
myString = myString.replace( /\&/g, '&' );
Paling mudah untuk melakukannya di sisi server karena ternyata JavaScript tidak memiliki pustaka asli untuk menangani entitas, juga saya tidak menemukan apa pun di dekat bagian atas hasil pencarian untuk berbagai kerangka kerja yang memperluas JavaScript.
Cari "entitas HTML JavaScript", dan Anda mungkin menemukan beberapa perpustakaan hanya untuk tujuan itu, tetapi mereka semua mungkin dibangun di sekitar logika di atas - ganti, entitas dengan entitas.
Saya hanya harus memiliki charater entitas HTML (⇓) sebagai nilai untuk tombol HTML. Kode HTML terlihat bagus dari awal di browser:
<input type="button" value="Embed & Share ⇓" id="share_button" />
Sekarang saya menambahkan toggle yang juga harus menampilkan karakter. Ini solusi saya
$("#share_button").toggle(
function(){
$("#share").slideDown();
$(this).attr("value", "Embed & Share " + $("<div>").html("⇑").text());
}
Ini menampilkan ⇓ lagi di tombol. Saya harap ini bisa membantu seseorang.
"Embed & Share \u21d1"
), atau lebih baik lagi hanya "Embed & Share ⇑"
jika Anda dapat melayani skrip Anda dalam UTF-8 (atau UTF-16, atau penyandian lain yang mendukung karakter ⇑). Menggunakan elemen DOM untuk mem-parsing entitas HTML hanya untuk memanggang karakter unicode sewenang-wenang menjadi string JavaScript adalah pendekatan licik dan kreatif yang akan membuat Rube Goldberg bangga, tetapi bukan praktik yang baik; unicode escapes ada dalam bahasa khusus untuk menangani use case ini.
Anda harus membuat fungsi khusus untuk entitas html:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
Misalkan Anda memiliki String di bawah ini.
Kabin Deluxe kami hangat, nyaman & amp; nyaman
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
str dan tetapkan kembali ke
menandai.
itu dia.
Untuk pengguna ExtJS, jika Anda sudah memiliki string yang disandikan, misalnya ketika nilai yang dikembalikan dari fungsi perpustakaan adalah konten innerHTML, pertimbangkan fungsi ExtJS ini:
Ext.util.Format.htmlDecode(innerHtmlContent)
Perpanjang kelas String:
String::decode = ->
$('<textarea />').html(this).text()
dan gunakan sebagai metode:
"<img src='myimage.jpg'>".decode()
Coba ini :
var htmlEntities = "<script>alert('hello');</script>";
var htmlDecode =$.parseHTML(htmlEntities)[0]['wholeText'];
console.log(htmlDecode);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
parseHTML adalah sebuah Fungsi di perpustakaan Jquery dan itu akan mengembalikan array yang menyertakan beberapa detail tentang String yang diberikan.
dalam beberapa kasus, String sedang besar, jadi fungsinya akan memisahkan konten ke banyak indeks ..
dan untuk mendapatkan semua data indeks Anda harus pergi ke indeks apa pun, kemudian akses ke indeks yang disebut "wholeText".
Saya memilih indeks 0 karena ini akan berfungsi dalam semua kasus (String kecil atau string besar).
Berikut ini masih ada satu masalah: String yang dilompati tidak terlihat dapat dibaca ketika ditugaskan ke nilai input
var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);
Exapmle: https://jsfiddle.net/kjpdwmqa/3/
escape
metode Underscore.js. Juga tidak ada penjelasan bagaimana sampel kode Anda harus menyelesaikan masalah OP.
Atau, ada juga perpustakaan untuk itu ..
di sini, https://cdnjs.com/libraries/he
npm install he //using node.js
<script src="js/he.js"></script> //or from your javascript directory
Penggunaannya adalah sebagai berikut ...
//to encode text
he.encode('© Ande & Nonso® Company LImited 2018');
//to decode the
he.decode('© Ande & Nonso® Company Limited 2018');
Bersulang.
Untuk mendekode Entitas HTML dengan jQuery, cukup gunakan fungsi ini:
function html_entity_decode(txt){
var randomID = Math.floor((Math.random()*100000)+1);
$('body').append('<div id="random'+randomID+'"></div>');
$('#random'+randomID).html(txt);
var entity_decoded = $('#random'+randomID).html();
$('#random'+randomID).remove();
return entity_decoded;
}
Cara Penggunaan:
Javascript:
var txtEncoded = "á é í ó ú";
$('#some-id').val(html_entity_decode(txtEncoded));
HTML:
<input id="some-id" type="text" />
Cara termudah adalah dengan menetapkan pemilih kelas ke elemen Anda dan kemudian gunakan kode berikut:
$(function(){
$('.classSelector').each(function(a, b){
$(b).html($(b).text());
});
});
Tidak ada lagi yang dibutuhkan!
Saya punya masalah ini dan menemukan solusi yang jelas dan berfungsi dengan baik.