JQuery ile HTML dizelerinden kaçma


609

Herkes jQuery dizelerden HTML kaçmak için kolay bir yol biliyor mu ? Ben rastgele bir dize geçmek ve düzgün bir HTML sayfasında (JavaScript / HTML enjeksiyon saldırılarını önleme) görüntülemek için kaçmış olması gerekir. Eminim bunu yapmak için jQuery genişletmek mümkün, ama şu anda bunu yapmak için çerçeve hakkında yeterli bilmiyorum.


Ayrıca bakınız perf: jsperf.com/…
Christophe Roussy

Yanıtlar:


445

JQuery kullandığınız için, öğenin textözelliğini ayarlayabilirsiniz :

// before:
// <div class="someClass">text</div>
var someHtmlString = "<script>alert('hi!');</script>";

// set a DIV's text:
$("div.someClass").text(someHtmlString);
// after: 
// <div class="someClass">&lt;script&gt;alert('hi!');&lt;/script&gt;</div>

// get the text in a string:
var escaped = $("<div>").text(someHtmlString).html();
// value: 
// &lt;script&gt;alert('hi!');&lt;/script&gt;

57
Kaçan sürümü almak için $ ("div.someClass"). Html () öğesine erişmeniz gereken noktayı kaçırdınız.
Morten Christiansen


20
@travis Bu, jQuery web sitesinde belgelenmiştir: "Farklı tarayıcılardaki HTML ayrıştırıcılarındaki farklılıklar nedeniyle, döndürülen metin yeni satırlarda ve diğer beyaz boşluklarda değişebilir." api.jquery.com/text
geofflee

3
@mklement Bu çözümü zaten kullanıyorsanız, bunun gibi bir şeyle ilgili herhangi bir sorun yaşamayacaksınız$(element2).attr("some-attr", $(element1).html()); : Bu örneğe bakın: jsbin.com/atibig/1/edit
travis

16
Bu kötü tırnak ve çift tırnak kaçmaz! wonko.com/post/html-escaping
Lior

601

Mustache.js'den de çözüm var

var entityMap = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#39;',
  '/': '&#x2F;',
  '`': '&#x60;',
  '=': '&#x3D;'
};

function escapeHtml (string) {
  return String(string).replace(/[&<>"'`=\/]/g, function (s) {
    return entityMap[s];
  });
}

7
Merakla, ondalık formatlı 'bir objeyle eşlendiğini , onaltılık formatı kullandığını unutmayın . /
mklement0

43
Bu kabul edilen cevap olmalıdır - basit, verimli, bağımlılık gerektirmez ve kesin olmayan korsanlarla amaçlananı tam olarak yapar.
lorefnon

6
dönüştürme \nkonusunda rehberlik <br>nedir?
amwinter

2
Burada kaynağa güncellenmiş bir bağlantı verilmiştir: github.com/janl/mustache.js/blob/…
mjackson

8
@amwinter, varlık haritasına "\ n": '<br>' ekleyerek yukarıdaki komut dosyasını genişlettim ve / [& <> "'\ /] | [\ n] / g
walv

182
$('<div/>').text('This is fun & stuff').html(); // "This is fun &amp; stuff"

Kaynak: http://debuggable.com/posts/encode-html-entities-with-jquery:480f4dd6-13cc-4ce9-8071-4710cbdd56cb


11
Yukarıdaki cevapta belirtildiği gibi, bu çözümün boşlukları koruyacağı garanti edilmez.
geofflee

47
Bunun tek veya çift tırnaklardan kaçmak için hiçbir şey yapmadığı unutulmamalıdır. değeri bir HTML özelliğine koymayı planlıyorsanız, bu bir sorun olabilir.
Kip

6
@Kip: @travis attr(), kodlanmamış dizelerin doğrudan iletilebilmesi için jQuery'nin yönteminin (en az 1.8.3'ten itibaren) kendi kodlamasını yaptığını buldu ; örneğin:$('<div/>').attr('test-attr', '\'Tis "fun" & stuff')[0].outerHTML
mklement0

1
@tarekahf Çok garip. Hangi jQuery sürümünü kullanıyorsunuz? Örnek kod, aynen kopyalayıp yapıştırırsanız çalışır mı? Burada en son jQuery (3.1.0) ile iyi çalışır: jsbin.com/fazimigayo/1/edit?html,js,console,output (ve önceki tüm sürümlerde de çalışması gerekir)
Henrik N

1
@tarekahf , DOM'ye bağlı olmayan $('<div/>')yeni bir divöğe oluşturur . Yani mevcut elemanları değiştirmez. JQuery'nin aynı $()işlevi hem elementleri ( $('div')) bulmak, hem de yaratmak için ve ayrıca birkaç şey için nasıl kullandığını biraz kafa karıştırıcı … :)
Henrik N

61

HTML'den kaçıyorsanız, gerçekten gerekli olacağını düşünebileceğim sadece üç tane var:

html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");

Senin kullanım durumuna bağlı olarak, gibi şeyler yapmak gerekebilir "için &quot;. Liste yeterince büyük olsaydı, sadece bir dizi kullanırdım:

var escaped = html;
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]
for(var item in findReplace)
    escaped = escaped.replace(findReplace[item][0], findReplace[item][1]);

encodeURIComponent() HTML için değil, yalnızca URL'ler için kaçacaktır.


13
Bu normal ifade, söz konusu HTML'de zaten kaçmış öğeler varsa garip sonuçlar üretir. Örneğin, "Tom & Jerry" 'den kaçmak "Tom & Jerry" üretir
Ryan

12
Lütfen yerel olarak varbeyan etmek için kullanın item; Neyse, for … inbir dizi üzerinden döngü yaparken hiç döngü kullanmayın ! forBunun yerine sıradan bir döngü kullanın. Oh, öyle encodeURIComponentdeğil escapeURIComponent.
Marcel Korpel

3
Etiket öznitelikleriyle çalışıyorsanız, tırnak işaretleri ve / veya çift tırnak işaretlerinden de kaçmanız gerekir. Htmlspecialchars için PHP belgeleri, gerçekleştirdiği dönüşümlerin yararlı bir listesini içerir. php.net/htmlspecialchars
geofflee

4
Yeni insanlar için sadece bir hatırlatma, web sitenizde bir yerde İngilizce olmayan karakterler olmasını istiyorsanız bunu kullanmayın ... Açıkçası bu 'é' gibi aksanlı karakterler nedeniyle yapmaz &eacute:; İşte html kişilerin listesi referans için verilmiştir: w3schools.com/tags/ref_entities.asp
LoganWolfer

11
@Ryan: Bu çözümün zaten kodlanmış dizeleri doğru şekilde işlemediğini belirtmekle birlikte, aynı şeyin bu sayfadaki çoğu - muhtemelen tüm çözümler için de geçerli olduğu hiçbir şeye değmez.
mklement0

37

Alt çizgi kullanmak için yeterince kolay:

_.escape(string) 

Alt çizgi , yerel j'lerin sağlamadığı birçok özellik sağlayan bir yardımcı program kütüphanesidir. Alt çizgiyle aynı API olan ancak daha performanslı olması için yeniden yazılan bir lodash da var .


36

Bunu yapan küçük bir işlev yazdım. Sadece kaçar ", &, <ve >(ama genellikle hepsi yine gerekmez var). Daha önce önerilen çözümlerden biraz daha zariftir, çünkü tüm dönüşümü yapmak için sadece birini kullanır .replace(). ( DÜZENLEME 2: İşlevi daha küçük ve daha düzenli hale getiren kod karmaşıklığı azaltıldı, orijinal kodu merak ediyorsanız bu cevabın sonuna bakın.)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&<>]/g, function (a) {
        return { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' }[a];
    });
}

Bu düz Javascripttir, jQuery kullanılmaz.

Kaçan /ve 'de

Mklement adlı kullanıcının yorumuna yanıt olarak düzenle .

Yukarıdaki fonksiyon herhangi bir karakteri içerecek şekilde kolaylıkla genişletilebilir. Kaçmak için daha fazla karakter belirtmek için, bunları hem normal ifadedeki karakter sınıfına (yani içinde /[...]/g) hem de chrnesneye bir giriş olarak eklemeniz yeterlidir . ( DÜZENLEME 2: Bu işlevi de aynı şekilde kısaltın.)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&'\/<>]/g, function (a) {
        return {
            '"': '&quot;', '&': '&amp;', "'": '&#39;',
            '/': '&#47;',  '<': '&lt;',  '>': '&gt;'
        }[a];
    });
}

&#39;Kesme işareti için yukarıdaki kullanımın ( &apos;bunun yerine sembolik varlık kullanılmış olabilir - XML'de tanımlanmıştır, ancak orijinal olarak HTML spesifikasyonuna dahil edilmemiştir ve bu nedenle tüm tarayıcılar tarafından desteklenmeyebilir. Bkz: HTML karakter kodlamaları hakkındaki Wikipedia makalesi. ). Ondalık varlıkları kullanmanın onaltılık kullanmaktan daha yaygın bir şekilde desteklendiğini de hatırlıyorum, ama şimdi bunun için kaynağı bulamıyorum. (Ve onaltılı varlıkları desteklemeyen çok sayıda tarayıcı olamaz.)

Not: HTML'de özel bir anlama sahip olmadıkları ve ihtiyaç duymadıkları için , kaçan karakterlerin listesine /ve eklemek 'o kadar da kullanışlı değildir. kaçtı edebilirsiniz.

Orijinal escapeHtmlİşlev

EDIT 2: Özgün işlev chr, .replace()geri arama için gereken nesneyi saklamak için bir değişken ( ) kullandı . Bu değişken ayrıca onu kapsamak için ekstra anonim bir işleve ihtiyaç duydu, bu da işlevi (gereksiz yere) biraz daha büyük ve daha karmaşık hale getirdi.

var escapeHtml = (function () {
    'use strict';
    var chr = { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };
    return function (text) {
        return text.replace(/[\"&<>]/g, function (a) { return chr[a]; });
    };
}());

İki sürümden hangisinin daha hızlı olduğunu test etmedim. Bunu yaparsanız, buraya bilgi ve bağlantılar eklemekten çekinmeyin.


Zaman ayırdığınız için teşekkürler, @Zrajm. Kaçmaya ihtiyaç duymama konusunda iyi bir nokta; neden ikisi de mustache.jsve herhangi bir fikir underscore.js? İkinci konuşma: sadece sayısal varlıkları (temsil tanır 've /içinde, ') büyük heks , form un kaçan. Böylece, metin kaçtı mustache.js- merakla bir hex karışımı kullanıyor . ve ondalık biçimler - doğru şekilde kaçınılmaz underscore.js. Diğer popüler kütüphanelerin bununla nasıl başa çıktığını merak ediyorum.
mklement0

1
Bu kütüphaneler dönüştürmek gerektiğini (muhtemelen) şeklidir böylece küçük harf altıgen şekli, en desteklenen şeklidir için . (Dönüştürürken Tabii ki her iki form çalışması gerekir dan .) - Kesme İşaretleri 'XML ayrılmış fonksiyonun çeşit XML (ancak HTML) adı geçen varlığı neden olan (ve dolayısıyla XHTML, hayal?) &apos;. Tam olarak neden ya da ne şekilde “ayrılmış” olduğunu bilmiyorum. - Eğik çizgiler URL'lerde özeldir, ancak bu aslında onları kaçan HTML'ye dahil edilmeleri için garanti etmez (URL kodlaması tamamen farklı bir şeydir).
zrajm

Re &apos;: doğru: sadece XHTML'de güvenli kullanım ; doğrudan kitle kaynağının ağzından - vurgu mayın: "(...) uygun bir HTML işlemcisi tarafından okunan , (...) 'veya özel varlık referanslarının kullanımı desteklenmeyebilir (...)" - pratikte : modern tarayıcılar HTML'de bile destekliyor . Onaltılık sayılarda durum. (aynı kaynak; vurgu mayını): "XML belgelerinde x küçük harf olmalıdır. […] Hhhh büyük ve küçük harfleri karıştırabilir, ancak büyük harf her zamanki stildir ." Eğik çizgileri kodlamaya kimin karar verdiğini merak ediyor; belki de gerçekten sadece URI ve HTML kodlaması arasında bir karışıklık?
mklement0

2
Son düşünceler: kodlamaya /gerek yok gibi görünüyor , ancak 'kodlanmış bir dizenin tek tırnak içine alınmış bir öznitelik değeri olarak kullanıldığı durumun güvenli bir şekilde ele alınması için kodlama yine de yararlı görünüyor .
mklement0

Her ikisi de yavaş. Çift basamaklı bir kenar boşluğunun en hızlı çözümü, işlevler yerine dizelerden geçirilen bir dizi yerine geçer.
Adam Leggett

34

Bu partiye ne kadar geç kaldığımı anlıyorum, ama jQuery gerektirmeyen çok kolay bir çözümüm var.

escaped = new Option(unescaped).innerHTML;

Düzenleme: Bu tırnak kaçmaz. Tırnak işaretlerinin kaçması gereken tek durum, içeriğin bir HTML dizesindeki bir özniteliğe satır içine yapıştırılıp yapıştırılmayacağıdır. Bunu yapmanın iyi bir tasarım olacağını düşünmek benim için zor.

Edit 3: En hızlı çözüm için yukarıdaki cevabı Saram'dan kontrol edin. Bu en kısa olanı.


Bu, tırnak işaretlerini değiştirmez - en azından şu anda Firefox 52'de.
getsetbro

1
Alıntılardan kaçmak yalnızca özniteliklerle işlevsel olarak ilgilidir. Kaçtığımız <ve >üretilen içeriğin amacı bir niteliğe girmediği sürece, alıntılardan kaçmanın hiçbir faydası yoktur.
Adam Leggett

31

İşte temiz ve net bir JavaScript işlevi. "Birkaç <çok" gibi metinden "birkaç <çok" a kaçacaktır.

function escapeHtmlEntities (str) {
  if (typeof jQuery !== 'undefined') {
    // Create an empty div to use as a container,
    // then put the raw text in and get the HTML
    // equivalent out.
    return jQuery('<div/>').text(str).html();
  }

  // No jQuery, so use string replace.
  return str
    .replace(/&/g, '&amp;')
    .replace(/>/g, '&gt;')
    .replace(/</g, '&lt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&apos;');
}

28

Son testlerden sonra en hızlı ve tamamen çapraz tarayıcı uyumlu yerel javaScript (DOM) çözümünü önerebilirim:

function HTMLescape(html){
    return document.createElement('div')
        .appendChild(document.createTextNode(html))
        .parentNode
        .innerHTML
}

Birçok kez tekrarlarsanız, bir kez hazırlanmış değişkenlerle yapabilirsiniz:

//prepare variables
var DOMtext = document.createTextNode("test");
var DOMnative = document.createElement("span");
DOMnative.appendChild(DOMtext);

//main work for each case
function HTMLescape(html){
  DOMtext.nodeValue = html;
  return DOMnative.innerHTML
}

Son performans karşılaştırmamı inceleyin ( yığın sorusu ).


2
İki düğüm kullanmak gerekli mi? Sadece bir tanesine ne dersiniz:var p = document.createElement('p'); p.textContent = html; return p.innerHTML;
Dan Dascalescu

2
@DanDascalescu: MDN'ye göre , textContentişlev yalnızca Chrome 1+, Firefox 2, IE9, Opera 9.64 ve Safari 3 tarafından desteklenmektedir (son ikisi "muhtemelen daha önce eklenmiştir"). Böylece OP'lerin "tamamen çapraz tarayıcı uyumlu" iddiasını bozacaktır.
zb226

p.innerText = html; return p.innerHTML
Bekim Bacaj

24

Underscore.string lib deneyin , jQuery ile çalışır.

_.str.escapeHTML('<div>Blah blah blah</div>')

çıktı:

'&lt;div&gt;Blah blah blah&lt;/div&gt;'

20
Ana alt çizgi kitaplığı artık bir _.escape()yardımcı program işlevine sahiptir.
codeape

15

escapeHTML()Dize nesnesine yöntemi ekleyerek mustache.js örneğini geliştirdim .

var __entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
};

String.prototype.escapeHTML = function() {
    return String(this).replace(/[&<>"'\/]/g, function (s) {
        return __entityMap[s];
    });
}

Bu şekilde kullanımı oldukça kolaydır "Some <text>, more Text&Text".escapeHTML()


Yararlı, ama aynı zamanda __entityMapyerel kapsama taşındım . Ve tüm bunlarıif (typeof String.prototype.escapeHTML !== 'function'){...}
FlameStorm

15

escape() ve unescape() , URL'ler için şifreleme / şifre çözme dizeleri değil amaçlanan HTML edilir.

Aslında, herhangi bir çerçeve gerektirmeyen hile yapmak için aşağıdaki snippet'i kullanıyorum:

var escapedHtml = html.replace(/&/g, '&amp;')
                      .replace(/>/g, '&gt;')
                      .replace(/</g, '&lt;')
                      .replace(/"/g, '&quot;')
                      .replace(/'/g, '&apos;');

Eğer "s'ye sahip olacaksanız, en azından 've `` dövüşe `` eklemeniz gerekir . Bunlar yalnızca html'deki öğelerin içindeki dize etiketi verileri için gerçekten gereklidir. Html verilerinin kendisi için (dış etiketler) sadece ilk 3 gereklidir.
Marius

10

Underscore.js'niz varsa, kullanın _.escape(yukarıda yayınlanan jQuery yönteminden daha verimli):

_.escape('Curly, Larry & Moe'); // returns: Curly, Larry &amp; Moe

5

Normal ifade yoluna gidiyorsanız, yukarıdaki tghw örneğinde bir hata var.

<!-- WON'T WORK -  item[0] is an index, not an item -->

var escaped = html; 
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g,"&gt;"], [/"/g,
"&quot;"]]

for(var item in findReplace) {
     escaped = escaped.replace(item[0], item[1]);   
}


<!-- WORKS - findReplace[item[]] correctly references contents -->

var escaped = html;
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]

for(var item in findReplace) {
     escaped = escaped.replace(findReplace[item[0]], findReplace[item[1]]);
}

2
Bunun için (findReplace var öğe) {escaped = escaped.replace (findReplace [item] [0], findReplace [item] [1]) olması gerektiğine inanıyorum; }
Chris Stephens

5

Bu güzel ve güvenli bir örnek ...

function escapeHtml(str) {
    if (typeof(str) == "string"){
        try{
            var newStr = "";
            var nextCode = 0;
            for (var i = 0;i < str.length;i++){
                nextCode = str.charCodeAt(i);
                if (nextCode > 0 && nextCode < 128){
                    newStr += "&#"+nextCode+";";
                }
                else{
                    newStr += "?";
                }
             }
             return newStr;
        }
        catch(err){
        }
    }
    else{
        return str;
    }
}

4
Orada ne tür istisnaları bastırıyorsunuz?
Stefan Majewsky

3

Vanilya js ile kolayca yapabilirsiniz.

Belgeye bir metin düğümü eklemeniz yeterlidir. Tarayıcıdan kaçacaktır.

var escaped = document.createTextNode("<HTML TO/ESCAPE/>")
document.getElementById("[PARENT_NODE]").appendChild(escaped)

2
(function(undefined){
    var charsToReplace = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;'
    };

    var replaceReg = new RegExp("[" + Object.keys(charsToReplace).join("") + "]", "g");
    var replaceFn = function(tag){ return charsToReplace[tag] || tag; };

    var replaceRegF = function(replaceMap) {
        return (new RegExp("[" + Object.keys(charsToReplace).concat(Object.keys(replaceMap)).join("") + "]", "gi"));
    };
    var replaceFnF = function(replaceMap) {
        return function(tag){ return replaceMap[tag] || charsToReplace[tag] || tag; };
    };

    String.prototype.htmlEscape = function(replaceMap) {
        if (replaceMap === undefined) return this.replace(replaceReg, replaceFn);
        return this.replace(replaceRegF(replaceMap), replaceFnF(replaceMap));
    };
})();

Global değişken yok, bazı bellek optimizasyonu. Kullanımı:

"some<tag>and&symbol©".htmlEscape({'©': '&copy;'})

sonuç:

"some&lt;tag&gt;and&amp;symbol&copy;"

2

JQUERY gerektirmeyen 2 basit yöntem ...

Dizenizdeki tüm karakterleri şu şekilde kodlayabilirsiniz :

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

Ya da sadece ana karakterleri hedef endişe yaklaşık &, satır sonları, <, >, "ve 'benzeri:

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

var myString='Encode HTML entities!\n"Safe" escape <script></'+'script> & other tags!';

test.value=encode(myString);

testing.innerHTML=encode(myString);

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<p><b>What JavaScript Generated:</b></p>

<textarea id=test rows="3" cols="55"></textarea>

<p><b>What It Renders Too In HTML:</b></p>

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


2

Basit JavaScript kaçan örneği:

function escapeHtml(text) {
    var div = document.createElement('div');
    div.innerText = text;
    return div.innerHTML;
}

escapeHtml("<script>alert('hi!');</script>")
// "&lt;script&gt;alert('hi!');&lt;/script&gt;"

3
Yalnızca kod yanıtları, sorunu nasıl çözdüklerini açıklamadığı için önerilmez. Bu sorunun daha önce kabul edilmiş ve onaylanmış diğer cevaplarda nasıl geliştiğini açıklamak için lütfen yanıtınızı güncelleyin . Ayrıca, bu soru 9 yaşındadır, çabalarınız son zamanlarda cevaplanmamış soruları olan kullanıcılar tarafından daha fazla takdir edilecektir. Lütfen İyi bir cevabı nasıl yazarım konusunu inceleyin .
FluffyKitten

1
@FluffyKitten burada bilmek istediğiniz her şeyi ayrıntılı olarak açıklayan bu işlevin avantajları ve dezavantajları hakkında son derece güzel yazılmış bir blog yazısı :) shebang.brandonmintern.com/…
db306 13:17

@ db306 Yalnızca kod yanıtı Yığın Taşması yönergelerine uymadığından yanıt düşük kalite olarak işaretlendi - bkz . İyi bir yanıt nasıl yazılır . Yorumum, gözden geçirme süreci sırasında neyin iyileştirilmesi gerektiğini açıklamak için eklenmiştir, yani cevabın kodun ne yaptığını ve mevcut cevaplarda nasıl geliştiğini açıklamak için güncellenmesi gerekmektedir. Upvotes bunu onaylamak için diğer gözden geçirenler vardır. Yorumlara harici bir bağlantı eklemek hala SO yönergelerini karşılamıyor. Bunun yerine Andrew'un ilgili bilgileri doğrudan cevabına dahil etmesi gerekiyor.
FluffyKitten

Brandonmintern DOT com'un süresinin dolduğunu ve şimdi park edildiğini unutmayın. Yeni shebang adresi shebang.mintern.net/foolproof-html-escaping-in-javascript/ şeklindedir.
Brandon

0
function htmlEscape(str) {
    var stringval="";
    $.each(str, function (i, element) {
        alert(element);
        stringval += element
            .replace(/&/g, '&amp;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(' ', '-')
            .replace('?', '-')
            .replace(':', '-')
            .replace('|', '-')
            .replace('.', '-');
    });
    alert(stringval);
    return String(stringval);
}

0
function htmlDecode(t){
   if (t) return $('<div />').html(t).text();
}

tıkır tıkır çalışıyor


metin html etiketlerini kaldırır, ancak $ ('<div />'). html (t) .html (); işleri
Bass Jobsen

0

Bu yanıt jQuery ve normal JS yöntemlerini sağlar, ancak bu DOM kullanılmadan en kısadır:

unescape(escape("It's > 20% less complicated this way."))

Kaçan dize: It%27s%20%3E%2020%25%20less%20complicated%20this%20way.

Kaçan alanlar sizi rahatsız ediyorsa şunu deneyin:

unescape(escape("It's > 20% less complicated this way.").replace(/%20/g, " "))

Kaçan dize: It%27s %3E 20%25 less complicated this way.

Ne yazık ki, escape()işlev JavaScript sürüm 1.5'te kullanımdan kaldırıldı . encodeURI()ya encodeURIComponent()da alternatiflerdir, ancak yok sayarlar ', bu nedenle son kod satırı buna dönüşür:

decodeURI(encodeURI("It's > 20% less complicated this way.").replace(/%20/g, " ").replace("'", '%27'))

Tüm büyük tarayıcılar hala kısa kodu destekliyor ve eski web sitelerinin sayısı göz önüne alındığında, yakında değişeceğinden şüphe duyuyorum.


Bu URL kodlaması içindir. Soru HTML çıkışından çok farklıydı.
thelem

@thelem, dizeleri HTML'de gömülü JavaScript dizilerine gömülmüşse değil, ancak metin olarak görüntülenebilmesi için düz HTML kaçışıyla ilgili olduğunu kabul ediyorum.
Cees Timmerman

0

Mustache.js çözümü için ES6 bir astar

const escapeHTML = str => (str+'').replace(/[&<>"'`=\/]/g, s => ({'&': '&amp;','<': '&lt;','>': '&gt;','"': '&quot;',"'": '&#39;','/': '&#x2F;','`': '&#x60;','=': '&#x3D;'})[s]);

-2

Bu bilgileri bir veritabanına kaydediyorsanız , istemci tarafı komut dosyası kullanarak HTML'den kaçmak yanlışsa, bunun sunucuda yapılması gerekir . Aksi takdirde XSS korumanızı atlamak kolaydır.

Demek istediğim, burada cevaplardan birini kullanan bir örnek:

Blogunuzdaki bir yorumdan Html'den kaçmak ve sonra sunucunuza göndermek için escapeHtml işlevini kullandığınızı varsayalım.

var entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
  };

  function escapeHtml(string) {
    return String(string).replace(/[&<>"'\/]/g, function (s) {
      return entityMap[s];
    });
  }

Kullanıcı şunları yapabilir:

  • POST istek parametrelerini düzenleyin ve yorumu javascript koduyla değiştirin.
  • Tarayıcı konsolunu kullanarak escapeHtml işlevinin üzerine yazın.

Kullanıcı bu snippet'i konsola yapıştırırsa, XSS doğrulamasını atlar:

function escapeHtml(string){
   return string
}

Katılmıyorum. Bu XSS korumasını atlamak için, aslında engellediğiniz şey olan bir XSS saldırısı (kaçmayı devre dışı bırakan bir komut dosyası enjekte etmek) kullanmanız gerekir. Bazı durumlarda, örneğin veriler standart JSON döndürmesi gereken bir REST API'sinden geliyorsa, istemciden kaçmak daha uygun olur.
İtalyaPaleAle

@Qualcuno Bu doğrulamayı istemcide yapıyorsanız ve bu bilgileri doğrulandığından emin olan sunucuya gönderiyorsanız, kullanıcı isteği kolayca düzenleyebilir ve komut dosyası veritabanına kaydedilir.
Kauê Gimenes

@Qualcuno Açıklamak için bazı örnekler ekledim.
Kauê Gimenes

1
Soru, sunucudan alınan dizeleri tarayıcıda görüntülemek için kaçmakla ilgiliydi . Söylediğiniz şey, dizeleri sunucuya göndermeden önce kaçmakla ilgilidir, bu farklı bir şeydir (haklısınız, oradasınız ve eski kurala geri döner , istemciden gelen herhangi bir girişi körü körüne asla kabul etmez )
ItalyPaleAle

@Qualcuno Bu Stackoverflow popüler bir soru, ve bu ele alınması gereken önemli bir nokta olduğuna inanıyorum. Bu yüzden cevap verdim.
Kauê Gimenes

-2

Yeniden kaçmayı engellemezseniz tüm çözümler işe yaramaz, örneğin çoğu çözüm kaçmaya devam &eder &amp;.

escapeHtml = function (s) {
    return s ? s.replace(
        /[&<>'"]/g,
        function (c, offset, str) {
            if (c === "&") {
                var substr = str.substring(offset, offset + 6);
                if (/&(amp|lt|gt|apos|quot);/.test(substr)) {
                    // already escaped, do not re-escape
                    return c;
                }
            }
            return "&" + {
                "&": "amp",
                "<": "lt",
                ">": "gt",
                "'": "apos",
                '"': "quot"
            }[c] + ";";
        }
    ) : "";
};

4
Buna çift çıkış adı verilir ve giriş verilerinizin önceden kaçmadığından emin olunması gerekir. Kelimenin tam anlamıyla & lt; kullanıcıya? Ya da belki metin başka bir yerde yeniden kullanılacak ve kaçışa bağlı olacak mı?
thelem
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.