Pengkodean HTML hilang ketika atribut membaca dari bidang input

745

Saya menggunakan JavaScript untuk menarik nilai dari bidang tersembunyi dan menampilkannya di kotak teks. Nilai dalam bidang tersembunyi disandikan.

Sebagai contoh,

<input id='hiddenId' type='hidden' value='chalk &amp; cheese' />

ditarik ke dalam

<input type='text' value='chalk &amp; cheese' />

melalui beberapa jQuery untuk mendapatkan nilai dari bidang tersembunyi (pada titik inilah saya kehilangan penyandian):

$('#hiddenId').attr('value')

Masalahnya adalah bahwa ketika saya membaca chalk &amp; cheesedari bidang tersembunyi, JavaScript tampaknya kehilangan penyandian. Saya tidak ingin nilainya chalk & cheese. Saya ingin yang harfiahamp; dipertahankan.

Apakah ada pustaka JavaScript atau metode jQuery yang akan meng-enkode string?

AJM
sumber
Bisakah Anda menunjukkan Javascript yang Anda gunakan?
Sinan Taifour
1
telah menambahkan bagaimana saya mendapatkan nilai dari bidang tersembunyi
AJM
5
JANGAN gunakan metode innerHTML (metode jQuery .html () menggunakan innerHTML), seperti pada beberapa browser (saya baru menguji Chrome), ini tidak akan keluar dari tanda kutip, jadi jika Anda meletakkan nilai Anda ke dalam nilai atribut , Anda akan berakhir dengan kerentanan XSS.
James Roper
21
dalam konteks apa chalkdan cheesepernah digunakan bersama 0_o
d -_- b
2
@d -_- b saat membandingkan dua item. contoh. mereka berbeda seperti kapur dan keju;)
Anurag

Jawaban:

1067

EDIT: Jawaban ini telah diposting lama, dan htmlDecodefungsinya memperkenalkan kerentanan XSS. Itu telah dimodifikasi mengubah elemen sementara dari divke textareamengurangi peluang XSS. Tetapi saat ini, saya akan mendorong Anda untuk menggunakan API DOMParser seperti yang disarankan di penjawab lainnya .


Saya menggunakan fungsi-fungsi ini:

function htmlEncode(value){
  // Create a in-memory element, set its inner text (which is automatically encoded)
  // Then grab the encoded contents back out. The element never exists on the DOM.
  return $('<textarea/>').text(value).html();
}

function htmlDecode(value){
  return $('<textarea/>').html(value).text();
}

Pada dasarnya elemen textarea dibuat dalam memori, tetapi tidak pernah ditambahkan ke dokumen.

Pada htmlEncodefungsi saya mengatur innerTextelemen, dan mengambil yang disandikan innerHTML; pada htmlDecodefungsi saya mengatur innerHTMLnilai elemen daninnerText diambil.

Lihat contoh yang sedang berjalan di sini .

CMS
sumber
95
Ini berfungsi untuk sebagian besar skenario, tetapi penerapan htmlDecode ini akan menghilangkan spasi kosong tambahan. Jadi untuk beberapa nilai "input", input! = HtmlDecode (htmlEncode (input)). Ini merupakan masalah bagi kami dalam beberapa skenario. Misalnya, jika input = "<p> \ t Hi \ n Di sana </p>", encode / decode bolak-balik akan menghasilkan "<p> Hai Di Sana </p>". Sebagian besar waktu ini baik-baik saja, tetapi terkadang tidak. :)
pettys
7
Terima kasih atas solusinya! Saya memecahkan masalah menghilangkan ruang kosong ekstra dengan mengganti baris baru dengan seperti %% NL %% dalam nilai teks, lalu memanggil .html () untuk mendapatkan nilai enkode HTML, lalu mengganti %% NL %% dengan <br /> ' s ... Bukan bukti peluru tetapi berfungsi dan pengguna saya tidak mungkin mengetikkan %% NL %%.
benno
1
Yang lucu adalah bahwa CSS memiliki white-spaceproperti, yang menunjukkan bagaimana ruang dalam konten HTML seharusnya diproses. Kehadiran kelayakan menyiratkan bahwa "ini adalah preformatted, spasi dan garis istirahat harus dipertahankan". Ini memecah pemisahan gaya dan konten, karena jika Anda mencoba memformat ulang HTML menjadi "cantik" atau Anda memutarnya melalui siklus encode / decode seperti ini, maka run spasi / istirahat berkurang, dan encoder tidak memiliki cara mengetahui apakah OK untuk melakukannya, karena tidak mengetahui white-space:pre-*;indikator dalam file CSS eksternal!
Triynko
2
Solusi ini dapat bergantung pada apakah halaman ditulis sebagai html atau xhtml, jadi saya akan memilih solusi yang tidak melibatkan DOM.
Phil H
30
Meskipun dijawab dua tahun kemudian, respons dari @Anentropic di bawah ini lebih baik dalam segala hal.
chad
559

Trik jQuery tidak menyandikan tanda kutip dan di IE itu akan menghapus spasi Anda.

Berdasarkan templatetag melarikan diri di Django, yang saya kira sudah banyak digunakan / diuji, saya membuat fungsi ini yang melakukan apa yang dibutuhkan.

Ini bisa dibilang lebih sederhana (dan mungkin lebih cepat) daripada pemecahan masalah untuk masalah pengupasan spasi putih - dan mengkodekan tanda kutip, yang penting jika Anda akan menggunakan hasil di dalam nilai atribut misalnya.

function htmlEscape(str) {
    return str
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
}

// I needed the opposite function today, so adding here too:
function htmlUnescape(str){
    return str
        .replace(/&quot;/g, '"')
        .replace(/&#39;/g, "'")
        .replace(/&lt;/g, '<')
        .replace(/&gt;/g, '>')
        .replace(/&amp;/g, '&');
}

Pembaruan 2013-06-17:
Dalam mencari pelarian tercepat saya telah menemukan implementasi replaceAllmetode ini:
http://dumpsite.com/forum/index.php?topic=4.msg29#msg29
(juga dirujuk di sini: Tercepat metode untuk mengganti semua instance karakter dalam string )
Beberapa hasil kinerja di sini:
http://jsperf.com/htmlencoderegex/25

Ini memberikan string hasil yang identik dengan replacerantai bawaan di atas. Aku akan sangat senang jika seseorang bisa menjelaskan mengapa ini lebih cepat !?

Pembaruan 2015-03-04:
Saya baru saja memperhatikan bahwa AngularJS menggunakan persis metode di atas:
https://github.com/angular/angular.js/blob/v1.3.14/src/ngSanitize/sanitize.js#L435

Mereka menambahkan beberapa penyempurnaan - mereka tampaknya menangani masalah Unicode yang tidak jelas serta mengubah semua karakter non-alfanumerik ke entitas. Saya mendapat kesan bahwa yang terakhir tidak diperlukan selama Anda memiliki charset UTF8 yang ditentukan untuk dokumen Anda.

Saya akan perhatikan bahwa (4 tahun kemudian) Django masih tidak melakukan hal-hal ini, jadi saya tidak yakin seberapa pentingnya hal itu:
https://github.com/django/django/django/blob/1.8b1/django/utils /html.py#L44

Pembaruan 2016-04-06:
Anda mungkin juga ingin melarikan diri ke garis miring /. Ini tidak diperlukan untuk penyandian HTML yang benar, namun direkomendasikan oleh OWASP sebagai langkah keamanan anti-XSS. (terima kasih kepada @JNF untuk menyarankan ini dalam komentar)

        .replace(/\//g, '&#x2F;');
Anentropik
sumber
3
Anda juga dapat menggunakan &apos;sebagai ganti&#39;
Ferruccio
5
Terima kasih, saya tidak pernah menyadari bahwa &apos;itu bukan entitas HTML yang valid.
Ferruccio
10
Tanpa itu /g, .replace()hanya akan menggantikan pertandingan pertama.
ThinkingStiff
1
@ Pelacak1 Saya tidak setuju, jika fungsinya menerima input yang tidak benar, ia harus membuat kesalahan. Jika dalam kasus penggunaan tertentu Anda ingin menangani input yang tidak valid dengan cara itu maka periksa nilainya sebelum memanggil fungsi atau bungkus panggilan fungsi dalam try / catch.
Anentropic
80

Berikut adalah versi non-jQuery yang jauh lebih cepat daripada .html()versi jQuery dan .replace()versi. Ini mempertahankan semua spasi putih, tetapi seperti versi jQuery, tidak menangani tanda kutip.

function htmlEncode( html ) {
    return document.createElement( 'a' ).appendChild( 
        document.createTextNode( html ) ).parentNode.innerHTML;
};

Kecepatan: http://jsperf.com/htmlencoderegex/17

tes kecepatan

Demo: jsFiddle

Keluaran:

keluaran

Naskah:

function htmlEncode( html ) {
    return document.createElement( 'a' ).appendChild( 
        document.createTextNode( html ) ).parentNode.innerHTML;
};

function htmlDecode( html ) {
    var a = document.createElement( 'a' ); a.innerHTML = html;
    return a.textContent;
};

document.getElementById( 'text' ).value = htmlEncode( document.getElementById( 'hidden' ).value );

//sanity check
var html = '<div>   &amp; hello</div>';
document.getElementById( 'same' ).textContent = 
      'html === htmlDecode( htmlEncode( html ) ): ' 
    + ( html === htmlDecode( htmlEncode( html ) ) );

HTML:

<input id="hidden" type="hidden" value="chalk    &amp; cheese" />
<input id="text" value="" />
<div id="same"></div>
ThinkingStiff
sumber
17
Ini menimbulkan pertanyaan: mengapa bukan fungsi global di JS ?!
SEoF
2
versi non-regex yang .replace()baru-baru ini disarankan oleh @SEoF ternyata jauh lebih cepat: jsperf.com/htmlencoderegex/22
Anentropic
@Anentropic Itu memang pencahayaan cepat, tapi saya pikir itu tidak berfungsi. Tanpa /g, .replace()hanya melakukan pertandingan pertama.
ThinkingStiff
Menariknya di Firefox Anda dapat melakukan replace('a', 'b', 'g')yang bekerja sama dengan replace(/a/g, 'b')... kecepatan juga identik
Anentropic
1
saya juga :) Saya mulai hanya ingin menangani tanda kutip dan saya akhirnya mencari kecepatan ...
Anentropic
32

Saya tahu ini adalah yang lama, tetapi saya ingin memposting variasi jawaban yang diterima yang akan berfungsi di IE tanpa menghapus baris:

function multiLineHtmlEncode(value) {
    var lines = value.split(/\r\n|\r|\n/);
    for (var i = 0; i < lines.length; i++) {
        lines[i] = htmlEncode(lines[i]);
    }
    return lines.join('\r\n');
}

function htmlEncode(value) {
    return $('<div/>').text(value).html();
} 
boca
sumber
29

Underscore menyediakan _.escape()dan _.unescape()metode yang melakukan ini.

> _.unescape( "chalk &amp; cheese" );
  "chalk & cheese"

> _.escape( "chalk & cheese" );
  "chalk &amp; cheese"
TJ VanToll
sumber
Lodash juga memiliki metode serupa.
Gustavo Straube
12

Jawaban yang bagus. Perhatikan bahwa jika nilai untuk menyandikan adalah undefinedatau nulldengan jQuery 1.4.2 Anda mungkin mendapatkan kesalahan seperti:

jQuery("<div/>").text(value).html is not a function

ATAU

Uncaught TypeError: Object has no method 'html'

Solusinya adalah memodifikasi fungsi untuk memeriksa nilai aktual:

function htmlEncode(value){ 
    if (value) {
        return jQuery('<div/>').text(value).html(); 
    } else {
        return '';
    }
}
leepower
sumber
8
jQuery('<div/>').text(value || '').html()
roufamatic
3
@roufamatic - Nice one-liner. Tetapi memeriksa non-kosong valuedengan ifmenghemat harus membuat DIV dengan cepat dan ambil nilainya. Ini bisa menjadi jauh lebih berkinerja jika htmlEncodedipanggil banyak DAN jika itu kemungkinan valueakan kosong.
leepowers
Hai itu tidak melakukan β ke & beta Anda tahu mengapa?
Dilip Rajkumar
11

Bagi mereka yang lebih suka javascript biasa, berikut adalah metode yang berhasil saya gunakan:

function escapeHTML (str)
{
    var div = document.createElement('div');
    var text = document.createTextNode(str);
    div.appendChild(text);
    return div.innerHTML;
}
timodius
sumber
6

FWIW, pengkodean tidak hilang. Pengkodean digunakan oleh parser markup (browser) selama pemuatan halaman. Setelah sumber dibaca dan diuraikan dan browser memiliki DOM dimuat ke dalam memori, pengkodean telah diuraikan menjadi apa yang diwakilinya. Jadi pada saat JS Anda dieksekusi untuk membaca apa pun dalam memori, karakter yang didapat adalah apa yang diwakili oleh pengkodean.

Saya mungkin beroperasi secara ketat pada semantik di sini, tetapi saya ingin Anda memahami tujuan pengkodean. Kata "hilang" membuatnya terdengar seperti sesuatu yang tidak berfungsi sebagaimana mestinya.

JAAulde
sumber
6

Lebih cepat tanpa Jquery. Anda dapat menyandikan setiap karakter di string Anda:

function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}

Atau hanya menargetkan karakter utama yang perlu dikhawatirkan (&, inebreaks, <,>, "dan ') seperti:

function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}

test.value=encode('Encode HTML entities!\n\n"Safe" escape <script id=\'\'> & useful in <pre> tags!');

testing.innerHTML=test.value;

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55"></textarea>

<div id="testing">www.WHAK.com</div>

Dave Brown
sumber
5

Prototipe memilikinya built-in kelas String . Jadi jika Anda menggunakan / berencana untuk menggunakan Prototipe, ia melakukan sesuatu seperti:

'<div class="article">This is an article</div>'.escapeHTML();
// -> "&lt;div class="article"&gt;This is an article&lt;/div&gt;"
Sinan Taifour
sumber
9
Setelah melihat solusi Prototipe, ini yang dilakukannya ... .replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;'); Cukup mudah.
Steve Wortham
5
tidakkah seharusnya ia melakukan sesuatu dengan tanda kutip juga? itu tidak baik
Anentropic
@Anentropic Saya tidak mengerti mengapa perlu melakukan apa pun dengan tanda kutip; sebagai kutipan tidak perlu diloloskan kecuali mereka berada di dalam nilai atribut.
Andy
OK setelah refleksi beberapa saya mengambil komentar itu kembali - jika Anda membangun sepotong HTML Anda ingin mengkodekan setiap bagian termasuk nilai atribut, jadi saya setuju dengan Anentropic dan saya tidak berpikir fungsi Prototypejs cukup dalam kasus itu.
Andy
4

Berikut ini adalah solusi javascript sederhana. Itu memperluas objek String dengan metode "HTMLEncode" yang dapat digunakan pada objek tanpa parameter, atau dengan parameter.

String.prototype.HTMLEncode = function(str) {
  var result = "";
  var str = (arguments.length===1) ? str : this;
  for(var i=0; i<str.length; i++) {
     var chrcode = str.charCodeAt(i);
     result+=(chrcode>128) ? "&#"+chrcode+";" : str.substr(i,1)
   }
   return result;
}
// TEST
console.log("stetaewteaw æø".HTMLEncode());
console.log("stetaewteaw æø".HTMLEncode("æåøåæå"))

Saya telah membuat intisari "metode HTMLEncode untuk javascript" .

Netsi1964
sumber
3

Berdasarkan sanitasi sudut ... (es6 modul syntax)

// ref: https://github.com/angular/angular.js/blob/v1.3.14/src/ngSanitize/sanitize.js
const SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
const NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;

const decodeElem = document.createElement('pre');


/**
 * Decodes html encoded text, so that the actual string may
 * be used.
 * @param value
 * @returns {string} decoded text
 */
export function decode(value) {
  if (!value) return '';
  decodeElem.innerHTML = value.replace(/</g, '&lt;');
  return decodeElem.textContent;
}


/**
 * Encodes all potentially dangerous characters, so that the
 * resulting string can be safely inserted into attribute or
 * element text.
 * @param value
 * @returns {string} encoded text
 */
export function encode(value) {
  if (value === null || value === undefined) return '';
  return String(value).
    replace(/&/g, '&amp;').
    replace(SURROGATE_PAIR_REGEXP, value => {
      var hi = value.charCodeAt(0);
      var low = value.charCodeAt(1);
      return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
    }).
    replace(NON_ALPHANUMERIC_REGEXP, value => {
      return '&#' + value.charCodeAt(0) + ';';
    }).
    replace(/</g, '&lt;').
    replace(/>/g, '&gt;');
}

export default {encode,decode};
Pelacak1
sumber
Sementara saya benar-benar menyukai jawaban ini dan sebenarnya saya pikir ini adalah pendekatan yang baik saya ragu, apakah operator bitwise pada if (value === null | value === undefined) return '';kesalahan ketik atau sebenarnya fitur? Jika demikian, mengapa menggunakan yang itu dan bukan yang biasa ||? Terima kasih!!
Alejandro Vales
1
@AlejandroVales Saya cukup yakin itu salah ketik ... diperbaiki.
Tracker1
1
Yah bagaimanapun juga perlu diingat bahwa | akan mengarah ke 0 atau 1, jadi sebenarnya itu berhasil ^^
Alejandro Vales
tidak bisakah kamu menggunakan saja == null? undefinedadalah satu-satunya hal yang memiliki kesetaraan dengan null, jadi dua triple-sama tidak diperlukan pula
Hashbrown
itu tidak benar sama sekali. nulldan 0keduanya palsu, ya, jadi Anda tidak bisa melakukannya !value, tetapi intinya ==adalah membuat hal-hal tertentu lebih mudah. 0 == nullitu salah. undefined == nulladalah benar. Anda bisa melakukannyavalue == null
Hashbrown
3

Sejauh yang saya tahu tidak ada metode HTML Encode / Decode langsung di javascript.

Namun, yang dapat Anda lakukan, adalah menggunakan JS untuk membuat elemen arbitrer, mengatur teks dalamnya, lalu membacanya menggunakan innerHTML.

Katakanlah, dengan jQuery, ini seharusnya berfungsi:

var helper = $('chalk & cheese').hide().appendTo('body');
var htmled = helper.html();
helper.remove();

Atau sesuatu seperti ini.

Ken Egozi
sumber
Saya menemukan downvote sedikit lucu, mengingat jawaban ini hampir identik dengan yang memiliki lebih dari 870 upvotes, dan telah diposting sedikit setelah ini.
Ken Egozi
2

Anda tidak perlu melarikan diri / menyandikan nilai untuk memindahkannya dari satu bidang input ke yang lain.

<form>
 <input id="button" type="button" value="Click me">
 <input type="hidden" id="hiddenId" name="hiddenId" value="I like cheese">
 <input type="text" id="output" name="output">
</form>
<script>
    $(document).ready(function(e) {
        $('#button').click(function(e) {
            $('#output').val($('#hiddenId').val());
        });
    });
</script>

JS tidak pergi menyisipkan HTML mentah atau apa pun; itu hanya memberitahu DOM untuk mengatur valueproperti (atau atribut; tidak yakin). Apa pun itu, DOM menangani masalah pengodean apa pun untuk Anda. Kecuali Anda melakukan sesuatu yang aneh seperti menggunakan document.writeatau eval, penyandian-HTML akan transparan secara efektif.

Jika Anda berbicara tentang membuat kotak teks baru untuk menahan hasilnya ... masih mudah. Cukup lewati bagian statis HTML ke jQuery, lalu setel properti / atribut lainnya pada objek yang dikembalikannya kepada Anda.

$box = $('<input type="text" name="whatever">').val($('#hiddenId').val());
cao
sumber
2

Saya memiliki masalah yang sama dan menyelesaikannya menggunakan fungsi encodeURIComponentdari JavaScript ( dokumentasi )

Misalnya, dalam kasus Anda jika Anda menggunakan:

<input id='hiddenId' type='hidden' value='chalk & cheese' />

dan

encodeURIComponent($('#hiddenId').attr('value'))

kamu akan mendapatkan chalk%20%26%20cheese. Bahkan ruang disimpan.

Dalam kasus saya, saya harus menyandikan satu backslash dan kode ini berfungsi dengan baik

encodeURIComponent('name/surname')

dan aku mengerti name%2Fsurname

Dmyan
sumber
2

Inilah sedikit yang mengemulasi Server.HTMLEncodefungsi dari ASP Microsoft, ditulis dalam JavaScript murni:

function htmlEncode(s) {
  var ntable = {
    "&": "amp",
    "<": "lt",
    ">": "gt",
    "\"": "quot"
  };
  s = s.replace(/[&<>"]/g, function(ch) {
    return "&" + ntable[ch] + ";";
  })
  s = s.replace(/[^ -\x7e]/g, function(ch) {
    return "&#" + ch.charCodeAt(0).toString() + ";";
  });
  return s;
}

Hasilnya tidak menyandikan apostrof, tetapi menyandikan spesial HTML lainnya dan karakter apa pun di luar rentang 0x20-0x7e.

Menulis kembali
sumber
2

Fungsi pure-JS saya:

/**
 * HTML entities encode
 *
 * @param {string} str Input text
 * @return {string} Filtered text
 */
function htmlencode (str){

  var div = document.createElement('div');
  div.appendChild(document.createTextNode(str));
  return div.innerHTML;
}

JavaScript HTML Entode Encode & Decode

Nick Tsai
sumber
1

Jika Anda ingin menggunakan jQuery. Aku menemukan ini:

http://www.jquerysdk.com/api/jQuery.htmlspecialchars

(bagian dari jquery.string plugin yang ditawarkan oleh jQuery SDK)

Masalah dengan Prototipe yang saya percaya adalah bahwa ia memperluas objek dasar dalam JavaScript dan tidak akan kompatibel dengan jQuery yang mungkin Anda gunakan. Tentu saja, jika Anda sudah menggunakan Prototipe dan bukan jQuery, itu tidak akan menjadi masalah.

EDIT: Juga ada ini, yang merupakan port dari utilitas string Prototype untuk jQuery:

http://stilldesigning.com/dotstring/

Sam Saint-Pettersen
sumber
1
var htmlEnDeCode = (function() {
    var charToEntityRegex,
        entityToCharRegex,
        charToEntity,
        entityToChar;

    function resetCharacterEntities() {
        charToEntity = {};
        entityToChar = {};
        // add the default set
        addCharacterEntities({
            '&amp;'     :   '&',
            '&gt;'      :   '>',
            '&lt;'      :   '<',
            '&quot;'    :   '"',
            '&#39;'     :   "'"
        });
    }

    function addCharacterEntities(newEntities) {
        var charKeys = [],
            entityKeys = [],
            key, echar;
        for (key in newEntities) {
            echar = newEntities[key];
            entityToChar[key] = echar;
            charToEntity[echar] = key;
            charKeys.push(echar);
            entityKeys.push(key);
        }
        charToEntityRegex = new RegExp('(' + charKeys.join('|') + ')', 'g');
        entityToCharRegex = new RegExp('(' + entityKeys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
    }

    function htmlEncode(value){
        var htmlEncodeReplaceFn = function(match, capture) {
            return charToEntity[capture];
        };

        return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn);
    }

    function htmlDecode(value) {
        var htmlDecodeReplaceFn = function(match, capture) {
            return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10));
        };

        return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn);
    }

    resetCharacterEntities();

    return {
        htmlEncode: htmlEncode,
        htmlDecode: htmlDecode
    };
})();

Ini dari kode sumber ExtJS.

WaiKit Kung
sumber
1
<script>
String.prototype.htmlEncode = function () {
    return String(this)
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');

}

var aString = '<script>alert("I hack your site")</script>';
console.log(aString.htmlEncode());
</script>

Akan menghasilkan: &lt;script&gt;alert(&quot;I hack your site&quot;)&lt;/script&gt;

.htmlEncode () akan dapat diakses di semua string setelah ditentukan.

Stuart Eske
sumber
1

HtmlEkode nilai yang diberikan

  var htmlEncodeContainer = $('<div />');
  function htmlEncode(value) {
    if (value) {
      return htmlEncodeContainer.text(value).html();
    } else {
      return '';
    }
  }
Sky Yip
sumber
1

Saya mengalami beberapa masalah dengan backslash di string Domain \ User.

Saya menambahkan ini ke jawaban lain dari jawaban Anentropic

.replace(/\\/g, '&#92;')

Yang saya temukan di sini: Bagaimana cara menghindari backslash dalam JavaScript?

spacebread
sumber
0

Memilih apa escapeHTML() yang dilakukan di prototype.js

Menambahkan skrip ini membantu Anda melarikan diriHTML:

String.prototype.escapeHTML = function() { 
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
}

sekarang Anda dapat memanggil metode escapeHTML pada string di skrip Anda, seperti:

var escapedString = "<h1>this is HTML</h1>".escapeHTML();
// gives: "&lt;h1&gt;this is HTML&lt;/h1&gt;"

Semoga ini membantu siapa pun yang mencari solusi sederhana tanpa harus menyertakan seluruh prototipe.js

Sahith Vibudhi
sumber
0

Dengan menggunakan beberapa jawaban lain di sini saya membuat versi yang menggantikan semua karakter terkait dalam satu pass terlepas dari jumlah karakter yang dikodekan berbeda (hanya satu panggilan ke replace()) sehingga akan lebih cepat untuk string yang lebih besar.

Itu tidak bergantung pada DOM API untuk ada atau di perpustakaan lain.

window.encodeHTML = (function() {
    function escapeRegex(s) {
        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    }
    var encodings = {
        '&'  : '&amp;',
        '"'  : '&quot;',
        '\'' : '&#39;',
        '<'  : '&lt;',
        '>'  : '&gt;',
        '\\' : '&#x2F;'
    };
    function encode(what) { return encodings[what]; };
    var specialChars = new RegExp('[' +
        escapeRegex(Object.keys(encodings).join('')) +
    ']', 'g');

    return function(text) { return text.replace(specialChars, encode); };
})();

Setelah menjalankannya sekali, sekarang Anda dapat menelepon

encodeHTML('<>&"\'')

Mendapatkan &lt;&gt;&amp;&quot;&#39;

Hashbrown
sumber
0

function encodeHTML(str) {
    return document.createElement("a").appendChild( 
        document.createTextNode(str)).parentNode.innerHTML;
};

function decodeHTML(str) {
    var element = document.createElement("a"); 
    element.innerHTML = str;
    return element.textContent;
};
var str = "<"
var enc = encodeHTML(str);
var dec = decodeHTML(enc);
console.log("str: " + str, "\nenc: " + enc, "\ndec: " + dec);

Israel
sumber