Ontsnappen aan HTML-tekenreeksen met jQuery

Weet iemand een gemakkelijke manier om HTML te ontsnappen aan strings in jQuery? Ik moet in staat zijn om een willekeurige string door te geven en deze correct te laten escapen voor weergave op een HTML-pagina (waardoor JavaScript/HTML-injectie-aanvallen worden voorkomen). Ik weet zeker dat het mogelijk is om jQuery uit te breiden om dit te doen, maar ik weet op dit moment niet genoeg over het framework om dit te bereiken.


Antwoord 1, autoriteit 100%

Aangezien je jQuerygebruikt, kun je de texteigenschap:

// 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;

Antwoord 2, autoriteit 93%

Er is ook de oplossing van snor.js

var entityMap = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#39;',
  '/': '&#x2F;',
  '`': '&#x60;',
  '=': '&#x3D;'
};
function escapeHtml (string) {
  return String(string).replace(/[&<>"'`=\/]/g, function (s) {
    return entityMap[s];
  });
}

Antwoord 3, autoriteit 40%

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

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


Antwoord 4, autoriteit 13%

Als je aan HTML ontsnapt, zijn er maar drie die ik kan bedenken die echt nodig zouden zijn:

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

Afhankelijk van uw gebruik, moet u mogelijk ook dingen doen als "tot &quot;. Als de lijst groot genoeg zou worden, zou ik gewoon een array:

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()zal het alleen escapen voor URL’s, niet voor HTML.


Antwoord 5, autoriteit 8%

Eenvoudig genoeg om onderstrepingstekens te gebruiken:

_.escape(string) 

Underscoreis een hulpprogrammabibliotheek die veel functies biedt die native js niet biedt. Er is ook lodash, dezelfde API als underscore, maar herschreven om beter te presteren.


6, Autoriteit 8%

Ik besef hoe laat ik ben naar dit feest, maar ik heb een zeer eenvoudige oplossing die geen jQuery nodig heeft.

escaped = new Option(unescaped).innerHTML;

Bewerken: dit is niet toegestaan tussen aanhalingstekens. Het enige geval waarin aanhalingstekens moeten worden ontsnapt, is als de inhoud inline wordt geplakt in een attribuut binnen een HTML-tekenreeks. Ik kan me moeilijk een geval voorstellen waarin dit een goed ontwerp zou zijn.

Bewerken 3: Bekijk voor de snelste oplossing het bovenstaande antwoord van Saram. Deze is de kortste.


Antwoord 7, autoriteit 7%

Hier is een schone, duidelijke JavaScript-functie. Het zal tekst zoals “een paar < veel” laten ontsnappen in “een paar &lt; veel”.

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;');
}

Antwoord 8, autoriteit 7%

Na de laatste tests kan ik snelsteen volledig cross browsercompatibele native javaScript(DOM) oplossing aanbevelen:

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

Als je het vaak herhaalt, kun je het doen met eenmaal voorbereide variabelen:

//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
}

Kijk naar mijn eindprestaties vergelijking (Stackvraag ).


9, Autoriteit 5%

Probeer underscore.string lib, het werkt met jQuery.

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

Uitgang:

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

10, Autoriteit 4%

escape()en unescape()zijn bedoeld om te coderen / decoderen van snaren voor URL’s, niet HTML.

Eigenlijk gebruik ik het volgende fragment om de truc te doen die geen raamwerk vereist:

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

11, Autoriteit 3%

Ik heb de snor.js-voorbeeld toegevoegd die de escapeHTML()-methode toevoegen aan het string-object.

var __entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
};
String.prototype.escapeHTML = function() {
    return String(this).replace(/[&<>"'\/]/g, function (s) {
        return __entityMap[s];
    });
}

Op die manier is het vrij eenvoudig om "Some <text>, more Text&Text".escapeHTML()

te gebruiken


Antwoord 12, autoriteit 2%

Als je underscore.js hebt, gebruik dan _.escape(efficiënter dan de jQuery-methode die hierboven is gepost):

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

Antwoord 13

Als je de reguliere route volgt, staat er een fout in het bovenstaande voorbeeld van tghw.

<!-- 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]]);
}

Antwoord 14

Dit is een mooi veilig voorbeeld…

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;
    }
}

15

U kunt het eenvoudig doen met vanille JS.

Voeg gewoon een tekstknooppunt toe aan het document.
Het zal worden ontsnapt door de browser.

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

16

2 eenvoudige methoden die geen jQuery vereisen …

U kunt coderen alle tekens in uw string als volgt:

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

of gewoon Target de hoofdpersonen om zich zorgen te maken over &, lijnonderbrekingen, <, >, "en 'zoals:

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>

Antwoord 17

(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));
    };
})();

Geen globale variabelen, enige geheugenoptimalisatie.
Gebruik:

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

resultaat is:

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

Antwoord 18

Eenvoudig JavaScript-escapevoorbeeld:

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;"

19

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);
}

20

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

werkt als een bedel


21

ES6 Eén voering voor de Oplossing van snor.js

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

22

Een snelheid-geoptimaliseerde versie:

function escapeHtml(s) {
   let out = "";
   let p2 = 0;
   for (let p = 0; p < s.length; p++) {
      let r;
      switch (s.charCodeAt(p)) {
         case 34: r = "&quot;"; break;  // "
         case 38: r = "&amp;" ; break;  // &
         case 39: r = "&#39;" ; break;  // '
         case 60: r = '&lt;'  ; break;  // <
         case 62: r = '&gt;'  ; break;  // >
         default: continue;
      }
      if (p2 < p) {
         out += s.substring(p2, p);
      }
      out += r;
      p2 = p + 1;
   }
   if (p2 == 0) {
      return s;
   }
   if (p2 < s.length) {
      out += s.substring(p2);
   }
   return out;
}
const s = "Hello <World>!";
document.write(escapeHtml(s));
console.log(escapeHtml(s));

Antwoord 23

Dit antwoordbiedt de jQuery en normale JS-methoden, maar dit is het kortst zonder de DOM te gebruiken:

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

Escaped string: It%27s%20%3E%2020%25%20less%20complicated%20this%20way.

Als de ontsnapte spaties je storen, probeer dan:

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

Escaped string: It%27s %3E 20%25 less complicated this way.

Helaas was de functie escape()verouderd in de JavaScript-versie 1.5. encodeURI()of encodeURIComponent()zijn alternatieven, maar ze negeren ', dus de laatste regel code zou dit worden:

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

Alle grote browsers ondersteunen nog steeds de korte code, en gezien het aantal oude websites, betwijfel ik of dat snel zal veranderen.


Antwoord 24

Alle oplossingen zijn nutteloos als u niet voorkomt dat u opnieuw kunt ontsnappen, b.v. de meeste oplossingen zouden blijven ontsnappen aan &naar &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] + ";";
        }
    ) : "";
};

Other episodes