जावास्क्रिप्ट में समतुल्य HtmlSpecialChars?


167

जाहिर है, यह मुझे लगता है कि यह होगा की तुलना में कठिन है। और यह इतना सरल भी है ...

क्या जावास्क्रिप्ट में निर्मित PHP के htmlspecialchars के बराबर एक फ़ंक्शन है? मुझे पता है कि यह अपने आप को लागू करना काफी आसान है, लेकिन एक अंतर्निहित फ़ंक्शन का उपयोग करना, यदि उपलब्ध है, तो बस अच्छा है।

PHP के साथ अपरिचित लोगों के लिए, htmlspecialchars सामान की तरह अनुवाद करता <htmltag/>है&lt;htmltag/&gt;

मुझे पता है कि escape()और encodeURI()इस तरह से काम नहीं करते हैं।


php को कुछ बहुत अच्छे टूल मिले हैं, var_dump, print_r, htmlspecialchars आदि। दुर्भाग्य से मुझे संदेह है कि यह js के साथ समान नहीं है। js का अलर्ट कितना घटिया है। यह देखने का एक तेज़ तरीका है कि कुछ अनपेक्षित (और अलर्ट बॉक्स में अदृश्य) स्ट्रिंग आ रही है, स्ट्रिंग की लंबाई के बजाय स्ट्रिंग की लंबाई को सचेत करना है।
मेल्सी


देखें stackoverflow.com/a/12034334/8804293 , इसका शानदार जवाब है
एलिय्याह मॉक

जवाबों:


330

आपके समाधान कोड के साथ एक समस्या है - यह केवल प्रत्येक विशेष चरित्र की पहली घटना से बच जाएगा। उदाहरण के लिए:

escapeHtml('Kip\'s <b>evil</b> "test" code\'s here');
Actual:   Kip&#039;s &lt;b&gt;evil</b> &quot;test" code's here
Expected: Kip&#039;s &lt;b&gt;evil&lt;/b&gt; &quot;test&quot; code&#039;s here

यहाँ कोड है जो ठीक से काम करता है:

function escapeHtml(text) {
  return text
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
}

अपडेट करें

निम्नलिखित कोड उपरोक्त के समान परिणाम देगा, लेकिन यह बेहतर प्रदर्शन करता है, विशेष रूप से पाठ के बड़े ब्लॉकों पर (धन्यवाद jbo5112 )।

function escapeHtml(text) {
  var map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };
  
  return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}

5
इस फ़ंक्शन के बारे में अच्छी बात यह है कि यह नोड में काम करता है। जेएस डिफ़ॉल्ट रूप से डोम नहीं करता है
बोआया

6
यह एकल प्रतिस्थापन और मानचित्रण फ़ंक्शन का उपयोग करने के लिए तेज़ है, और एकल प्रतिस्थापित स्केल बहुत बेहतर है। ( jsperf.com/escape-html-special-chars/11 )
jbo5112

1
@ jbo5112 अच्छा बिंदु, मुझे महसूस नहीं हुआ कि जेएस ने प्रतिस्थापन के लिए कॉलबैक की अनुमति दी थी। यह कोड हालांकि समझना आसान है, और मुझे संदेह है कि कुछ मिलीसेकेंड की शेविंग एस्केपहटल () से होने वाली है जब तक कि आप इसे किसी कारण से एक पंक्ति में सैकड़ों बार कॉल नहीं कर रहे हैं।
किप

यह पाठ में URL को विकृत कर देगा जो उन्हें Autolinker.js जैसे प्लगइन्स के लिए अनुपयोगी बनाता है । क्या कोई तरीका है कि इससे कैसे संपर्क किया जाए?
राडेक माटज

4
@ RadekMat Radej उस मामले में भी यह पूरी तरह से वैध है (बेहतर होगा कि मैं बहस करूँ) दोनों एम्परसेंड्स को HTML डॉक्यूमेंट में उपयोग किए जाने पर एन्कोड किया जाएगा। मैं अभी भी इसे प्लगइन के साथ एक बग पर विचार करूंगा।
किप

31

यह HTML एन्कोडिंग है। ऐसा करने के लिए कोई देशी जावास्क्रिप्ट फ़ंक्शन नहीं है, लेकिन आप Google और कुछ अच्छी तरह से कर सकते हैं।

जैसे http://sanzon.wordpress.com/2008/05/01/neat-little-html-encoding-trick-in-javascript/

संपादित करें:
यह वही है जो मैंने परीक्षण किया है:

var div = document.createElement('div');
  var text = document.createTextNode('<htmltag/>');
  div.appendChild(text);
  console.log(div.innerHTML);

आउटपुट: &lt;htmltag/&gt;


बहुत बुरा, मैं बस एक कस्टम फ़ंक्शन का उपयोग करना होगा।
बार्ट वैन ह्युकेलोम

आप मेरे पोस्ट में शामिल लिंक में विधि की कोशिश कर सकते हैं। बहुत साफ अवधारणा वास्तव में।
नवंबर'09 को ओके करें

@okw: ठीक है, पहले आप इस से जुड़े: yuki-onna.co.uk/html/encode.html जो ठीक वही करता है जो encodeURIComponentओपी ने नहीं पूछा। तो क्या आप कृपया संपादित कर सकते हैं? मैं अपने -1 को पूर्ववत नहीं कर सकता।
वर्धमान ताजा

याह, उस पृष्ठ का कोड तार्किक लगता है लेकिन मैंने इसका परीक्षण नहीं किया। नया लिंक हालांकि काम करता है, मैंने इसे स्वयं सत्यापित किया है। मैंने कुछ समय पहले ही पोस्ट को अपडेट किया है।
नवंबर'09 को ओके करें

@BeauCielBleu: नहीं। केवल बनाए गए नोड्स एक divतत्व और एक पाठ नोड हैं। टेक्स्ट के साथ टेक्स्ट नोड बनाना `<img src = bogus onerror = alert (1337)>` केवल एक टेक्स्ट नोड बनाएगा, imgतत्व नहीं ।
टिम डाउन

26

वर्थ ए रीड: http://bigdingus.com/2007/12/29/html-esformation-in-javascript/

escapeHTML: (function() {
 var MAP = {
   '&': '&amp;',
   '<': '&lt;',
   '>': '&gt;',
   '"': '&#34;',
   "'": '&#39;'
 };
  var repl = function(c) { return MAP[c]; };
  return function(s) {
    return s.replace(/[&<>'"]/g, repl);
  };
})()

नोट : इसे केवल एक बार चलाएं। और यह पहले से ही इनकोडिंग तार जैसे पर नहीं चला &amp;हो जाता है&amp;amp;


3
यह स्वीकृत और उच्चतम मतदान वाला उत्तर होना चाहिए। मुझे यकीन नहीं है कि इसके पास कोई वोट क्यों नहीं था। यह एक लंबी (326KB Google खोज परिणाम) और jsperf ( jsperf.com/escape-html-special-chars/11 ) पर शॉर्ट इनपुट स्ट्रिंग दोनों के साथ सबसे तेज़ बेंचमार्किंग है । कृपया इसे वोट करें।
jbo5112

इस एक जवाब के बीच क्या अंतर है जो सबसे ज्यादा वोट मिले। अतिरिक्त आंतरिक कार्य क्यों? एक स्पष्टीकरण उपयोगकर्ताओं को बेहतर समझने में मदद कर सकता है
कोसेम

19

JQuery के साथ यह इस प्रकार हो सकता है:

var escapedValue = $('<div/>').text(value).html();

संबंधित प्रश्न से jQuery के साथ HTML स्ट्रिंग को बचाना

जैसा कि टिप्पणी में उल्लेख किया गया है दोहरे उद्धरण और एकल उद्धरण इस कार्यान्वयन के लिए शेष हैं। इसका मतलब है कि इस समाधान का उपयोग नहीं किया जाना चाहिए यदि आपको कच्चे HTML स्ट्रिंग के रूप में तत्व विशेषता बनाने की आवश्यकता है।


2
किसी भी विचार अगर वहाँ कोई उपरि है - डोम के लिए एक डमी वस्तु जोड़ने?
किप

और क्या कोई अन्य लाभ हैं (कहते हैं, यदि आपके पास यूनिकोड वर्ण या कुछ है)?
किप

4
इसके साथ मुझे कुछ मिला: डबल कोट्स और सिंगल कोट्स को छोड़ दिया गया है। यदि आप इसे किसी विशेषता मान में उपयोग करना चाहते हैं, तो यह समस्याग्रस्त है।
किप

1
पाठ की छोटी मात्रा के लिए, यह 30x लेता है जब तक कि सभी जगह नहीं चलती। यह हालांकि बेहतर पैमाने पर है। Google खोज परिणाम पृष्ठ (326KB) के रूप में कुछ के साथ, यह सीधे जावास्क्रिप्ट की तुलना में 25-30% तेजी से या ऐसा कर रहा है। हालांकि, वे सभी लगातार एक ही प्रतिस्थापन और एक मैपिंग फ़ंक्शन से हार जाते हैं।
jbo5112

4
लोग इस जवाब पर कैसे वोट देते हैं: जवाब में jquery है: +1 - सिंगल और डबल कोट्स से नहीं बचता है: ummmm .. (स्क्रैचिंग हेड) .. +1। <!-- Caps rage begin --> इस जवाब का NEGATIVE स्कोर होना चाहिए क्योंकि यह "HtmlSpecialChars समतुल्य" के समकक्ष आने के लिए नहीं आया है। <!-- Caps rage end -->यह करता है-नहीं-एस्केप उद्धरण-यीशु मसीह-व अन्य-देवताओं। OMG तुम लोगों को jquery।
शर्की

19

यहाँ HTML से बचने के लिए एक समारोह है:

function escapeHtml(str)
{
    var map =
    {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
    };
    return str.replace(/[&<>"']/g, function(m) {return map[m];});
}

और डीकोड करने के लिए:

function decodeHtml(str)
{
    var map =
    {
        '&amp;': '&',
        '&lt;': '<',
        '&gt;': '>',
        '&quot;': '"',
        '&#039;': "'"
    };
    return str.replace(/&amp;|&lt;|&gt;|&quot;|&#039;/g, function(m) {return map[m];});
}

6

Underscore.js इसके लिए एक फ़ंक्शन प्रदान करता है:

_.escape(string)

HTML में प्रविष्टि के लिए एक स्ट्रिंग से बाहर निकलता है, और, <,>, ", और 'वर्णों को प्रतिस्थापित करता है।

http://underscorejs.org/#escape

यह एक अंतर्निहित जावास्क्रिप्ट फ़ंक्शन नहीं है, लेकिन यदि आप पहले से ही अंडरस्कोर का उपयोग कर रहे हैं, तो यह अपने स्वयं के फ़ंक्शन को लिखने से बेहतर विकल्प है यदि आपके स्ट्रिंग्स को कनवर्ट करने के लिए बहुत बड़ा नहीं है।


5

फिर भी इस पर एक और टेक सभी चरित्र मानचित्रण को पूरी तरह से छोड़ना है और इसके बजाय सभी अवांछित वर्णों को उनके संबंधित संख्यात्मक चरित्र संदर्भों में बदलना है, जैसे:

function escapeHtml(raw) {
    return raw.replace(/[&<>"']/g, function onReplace(match) {
        return '&#' + match.charCodeAt(0) + ';';
    });
}

ध्यान दें कि निर्दिष्ट RegEx केवल उन विशिष्ट वर्णों को संभालता है जिन्हें ओपी बचाना चाहता था लेकिन, इस संदर्भ के आधार पर कि बचा हुआ HTML उपयोग होने वाला है, ये वर्ण पर्याप्त नहीं हो सकते। रयान ग्रोव का लेख HTML से अधिक से भाग रहा है, <,>, और " विषय पर एक अच्छा पढ़ा है। और आपके संदर्भ के आधार पर, XSS इंजेक्शन से बचने के लिए निम्नलिखित RegEx की बहुत अच्छी आवश्यकता हो सकती है:

var regex = /[&<>"'` !@$%()=+{}[\]]/g

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

नमूना:

var toto = "test<br>";
alert(toto.escapeHTML());

3

संभावना है कि आप इस तरह के एक समारोह की जरूरत नहीं है। चूँकि आपका कोड पहले से ही ब्राउज़र * में है, आप HTML उत्पन्न करने और एन्कोडिंग करने के बजाय सीधे DOM तक पहुँच सकते हैं, जिसे वास्तव में उपयोग किए जाने वाले ब्राउज़र द्वारा पीछे की ओर डिकोड किया जाना होगा।

innerTextDOM में सादे पाठ को सम्मिलित करने के लिए संपत्ति का उपयोग करें और प्रस्तुत किए गए किसी भी भागने वाले कार्यों का उपयोग करने की तुलना में सुरक्षित रूप से बहुत तेज है। यहां तक ​​कि एक स्थिर प्रीकोडेड स्ट्रिंग को असाइन करने से भी तेजinnerHTML

classListकक्षाओं को संपादित करने के लिए, विशेषताओं datasetको सेट करने के लिए data-और setAttributeदूसरों के लिए उपयोग करें ।

ये सभी आपके लिए भागने से बचेंगे। अधिक सटीक रूप से, कोई भागने की आवश्यकता नहीं है और ** के नीचे कोई एन्कोडिंग नहीं किया जाएगा, क्योंकि आप HTML के आसपास काम कर रहे हैं, DOM का पाठात्मक प्रतिनिधित्व।

// use existing element
var author = 'John "Superman" Doe <john@example.com>';
var el = document.getElementById('first');
el.dataset.author = author;
el.textContent = 'Author: '+author;

// or create a new element
var a = document.createElement('a');
a.classList.add('important');
a.href = '/search?q=term+"exact"&n=50';
a.textContent = 'Search for "exact" term';
document.body.appendChild(a);

// actual HTML code
console.log(el.outerHTML);
console.log(a.outerHTML);
.important { color: red; }
<div id="first"></div>

* यह उत्तर सर्वर-साइड जावास्क्रिप्ट उपयोगकर्ताओं (Node.js, आदि) के लिए अभिप्रेत नहीं है ) के

** जब तक आप स्पष्ट रूप से इसे वास्तविक HTML में परिवर्तित नहीं करते हैं। जैसे पहुँच करinnerHTML - यह तब होता है जब आप $('<div/>').text(value).html();अन्य उत्तरों में सुझाए गए चलाते हैं । इसलिए यदि आपका अंतिम लक्ष्य दस्तावेज़ में कुछ डेटा सम्मिलित करना है, तो इस तरह से आप दो बार काम कर रहे हैं। इसके अलावा, आप देख सकते हैं कि परिणामी HTML में सब कुछ एनकोडेड नहीं है, केवल इसके लिए आवश्यक न्यूनतम ही वैध है। यह संदर्भ-निर्भरता से किया जाता है, यही कारण है कि यह jQuery पद्धति उद्धरणों को सांकेतिक शब्दों में बदलना नहीं करती है और इसलिए इसे एक सामान्य उद्देश्य के एस्केपर के रूप में उपयोग नहीं किया जाना चाहिए। जब आप HTML का निर्माण एक विशेषता के मान के स्थान पर अविश्वसनीय या उद्धरण युक्त डेटा के साथ एक स्ट्रिंग के रूप में कर रहे हों, तो उद्धरण से बचने की आवश्यकता होती है। यदि आप DOM API का उपयोग करते हैं, तो आपको भागने की बिल्कुल भी परवाह नहीं है।


इसके लिए धन्यवाद! मैं इस तरह के एक सरल समाधान की तलाश में लंबे समय तक बिता चुका हूं। एक महत्वपूर्ण बात जो मुझे पता चली है, वह यह है कि यदि आपके पाठ में नई लिंक हैं, तो आपको उन्हें HTML लाइन विराम (जैसे कुछ el.textContent = str; el.innerHTML = el.innerHTML.replace(/\n/g, '<br>')) के साथ बदलना होगा , या CSS white-spaceसंपत्ति को सेट करना होगा preयाpre-wrap
stellatedHexahedron

@stellatedHexahedron, इस मुद्दे को उठाने के लिए धन्यवाद। मैंने अपना उत्तर बदलने की सिफारिश innerTextकी है textContent। जबकि थोड़ा धीमा और संपत्ति को पढ़ते समय कुछ अन्य अंतर होते हैं, यह अधिक सहज है कि यह इसे <br>असाइन करते समय प्रतिस्थापन स्वचालित रूप से करता है।
उपयोगकर्ता

2

Node.JS उपयोगकर्ताओं (या ब्राउज़र में जेड रनटाइम का उपयोग करने वाले उपयोगकर्ता) के लिए, आप जेड के एस्केप फ़ंक्शन का उपयोग कर सकते हैं।

require('jade').runtime.escape(...);

इसे लिखने में कोई समझदारी नहीं है अगर कोई इसे बनाए रखता है। :)


1

मैं okw के जवाब पर थोड़ा विस्तार कर रहा हूं।

आप उस के लिए ब्राउज़र के DOM फ़ंक्शंस का उपयोग कर सकते हैं।

var utils = {
    dummy: document.createElement('div'),
    escapeHTML: function(s) {
        this.dummy.textContent = s
        return this.dummy.innerHTML
    }
}

utils.escapeHTML('<escapeThis>&')

यह लौटता है &lt;escapeThis&gt;&amp;

यह createElementएक अदृश्य तत्व बनाने के लिए मानक फ़ंक्शन का उपयोग करता है, फिर textContentकिसी भी स्ट्रिंग को अपनी सामग्री के रूप में सेट करने के लिए फ़ंक्शन का उपयोग करता है और फिर innerHTMLअपने HTML प्रतिनिधित्व में सामग्री प्राप्त करने के लिए।


0
function htmlspecialchars(str) {
 if (typeof(str) == "string") {
  str = str.replace(/&/g, "&amp;"); /* must do &amp; first */
  str = str.replace(/"/g, "&quot;");
  str = str.replace(/'/g, "&#039;");
  str = str.replace(/</g, "&lt;");
  str = str.replace(/>/g, "&gt;");
  }
 return str;
 }

0

आशा है कि यह अपने प्रदर्शन के कारण दौड़ जीतता है और सबसे महत्वपूर्ण है कि एक शुद्ध तर्क का उपयोग नहीं किया जाता है। ('&', 'और') का उपयोग करें। ('<', '<') को बदलें ...

var mapObj = {
   '&':"&amp;",
   '<':"&lt;",
   '>':"&gt;",
   '"':"&quot;",
   '\'':"&#039;"
};
var re = new RegExp(Object.keys(mapObj).join("|"),"gi");

function escapeHtml(str) 
{   
    return str.replace(re, function(matched)
    {
        return mapObj[matched.toLowerCase()];
    });
}

console.log('<script type="text/javascript">alert('Hello World');</script>');
console.log(escapeHtml('<script type="text/javascript">alert('Hello World');</script>'));

0

एक उलट:

function decodeHtml(text) {
    return text
        .replace(/&amp;/g, '&')
        .replace(/&lt;/ , '<')
        .replace(/&gt;/, '>')
        .replace(/&quot;/g,'"')
        .replace(/&#039;/g,"'");
}

सवाल यह नहीं पूछ रहा है कि संस्थाओं को कैसे डिकोड किया जाए। यह इसके विपरीत है जो सवाल पूछ रहा है।
क्वेंटिन

यह केवल जगह लेगा पहले के उदाहरण &lt;और &gr;एक स्ट्रिंग में।
क्वेंटिन

यह केवल पांच वर्णों को डिकोड करेगा जो (गैर-यूनिकोड दस्तावेजों के बाहर) को बचाना होगा, यह उन लोगों को डिकोड नहीं करेगा जो बच सकते हैं।
क्वेंटिन

सेमी-कोलोन वैकल्पिक होने पर यह नियमों को ध्यान में नहीं रखता है।
क्वेंटिन

एचटीएमएल कहते हैं: To write a greater than sign in HTML type &amp;gt;, इसे गलत तरीके से प्रदर्शित करेगा >बजाय&gt;
क्वेंटिन

0

OWASP अनुशंसा करता है कि "[e] अल्फ़ान्यूमेरिक वर्णों के लिए xcept, [आपको] [ &#xHH;a] विशेषता से बाहर जाने से रोकने के लिए प्रारूप (या यदि उपलब्ध नाम) के साथ २५६ से कम ASCII मान वाले सभी वर्णों से बचना चाहिए ।"

तो यहाँ एक फ़ंक्शन है जो एक उपयोग उदाहरण के साथ करता है:

function escapeHTML(unsafe) {
  return unsafe.replace(
    /[\u0000-\u002F]|[\u003A-\u0040]|[\u005B-\u00FF]/g,
    c => '&#' + ('000' + c.charCodeAt(0)).substr(-4, 4) + ';'
  )
}
document.querySelector('div').innerHTML =
  '<span class=' +
  escapeHTML('this should break it! " | / % * + , - / ; < = > ^') +
  '>' +
  escapeHTML('<script>alert("inspect the attributes")\u003C/script>') +
  '</span>'
<div></div>


-1
function htmlEscape(str){
    return str.replace(/[&<>'"]/g,x=>'&#'+x.charCodeAt(0)+';')
}

यह समाधान वर्णों के संख्यात्मक कोड का उपयोग करता है, उदाहरण के लिए <इसके द्वारा प्रतिस्थापित किया जाता है&#60;

यद्यपि इसका प्रदर्शन मानचित्र का उपयोग करते हुए समाधान से थोड़ा खराब है , इसके फायदे हैं:

  • लाइब्रेरी या DOM पर निर्भर नहीं
  • याद रखना बहुत आसान है (आपको 5 HTML एस्केप वर्ण याद करने की आवश्यकता नहीं है)
  • थोड़ा कोड
  • यथोचित तेजी से (यह अभी भी 5 जंजीर की तुलना में तेज है)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.