এইচটিএমএল ট্যাগগুলি এইচটিএমএল সত্তা হিসাবে পালানোর দ্রুততম পদ্ধতি?


100

আমি একটি ক্রোম এক্সটেনশন করে একটি করছেন জড়িত লিখছি অনেক স্ট্রিং যে sanitizing: নিম্নলিখিত কাজের পারে এইচটিএমএল ট্যাগ রয়েছে, রূপান্তর দ্বারা <, >এবং &থেকে &lt;, &gt;এবং &amp;যথাক্রমে।

(অন্য কথায়, পিএইচপি'র মতোই htmlspecialchars(str, ENT_NOQUOTES)- আমার মনে হয় না ডাবল-কোট অক্ষর রূপান্তরিত করার কোনও বাস্তব প্রয়োজন আছে need)

এটি আমি এখনও অবধি খুঁজে পেলাম:

function safe_tags(str) {
    return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;') ;
}

তবে এখনও অনেক বড় পিছিয়ে আছে যখন আমাকে এক সাথে কয়েক হাজার স্ট্রিং চালাতে হবে।

কেউ কি এই উন্নতি করতে পারেন? এটি বেশিরভাগ 10 এবং 150 টির মধ্যে স্ট্রিংয়ের জন্য থাকে, যদি এটি কোনও পার্থক্য করে।

(আমার কাছে একটি ধারণা ছিল যে বৃহত্তর চিহ্নটি এনকোডিং করা উচিত নয় - তাতে কি কোনও সত্যই বিপদ হবে?)


4
কেন? বেশিরভাগ ক্ষেত্রে আপনি এটি করতে চান, আপনি ডিওমে ডেটা inোকাতে চান, সেক্ষেত্রে আপনার এড়িয়ে যাওয়া সম্পর্কে ভুলে যাওয়া উচিত এবং এ থেকে একটি পাঠ্য নোড তৈরি করা উচিত।
কোয়ান্টিন

4
@ ডেভিড ডারওয়ার্ড: সম্ভবত তিনি পোস্টের তথ্য স্যানিটাইজ করতে চেয়েছিলেন, এবং সার্ভারটি ডেটাটি সঠিকভাবে গোল-ট্রিপ করে না।
মিথ্যা রায়ান

4
@ মিথ্যা - যদি তাই হয় তবে সমাধানটি হ'ল "পিটের পক্ষে, সার্ভারটি ঠিক করুন যেমন আপনার কাছে একটি বড় এক্সএসএস গর্ত আছে"
কোয়ান্টিন

4
@ ডেভিড ডারওয়ার্ড: সম্ভবত এটিই সম্ভব যে সার্ভারের উপর তার নিয়ন্ত্রণ নেই। আমি সম্প্রতি এমন পরিস্থিতিতে পড়েছি যেখানে আমি আমার বিশ্ববিদ্যালয়ের ওয়েবসাইটে আমার পছন্দ না হওয়া কয়েকটি বিষয় নিয়ে কাজ করার জন্য গ্রীসমনকি স্ক্রিপ্ট লিখছিলাম; আমার একটি সার্ভারে একটি পোস্ট করতে হয়েছিল যা জাভাস্ক্রিপ্ট ব্যবহার করে পোষ্টের ডেটা নিয়ন্ত্রণ ও স্যানিটাইজ করার মতো আমার নিয়ন্ত্রণ নেই (যেহেতু কাঁচা ডেটা একটি সমৃদ্ধ পাঠ্যবাক্স থেকে আসে, এবং এতে এইচটিএমএল ট্যাগ রয়েছে যা সার্ভারে রাউন্ড ট্রিপ করে না) । ওয়েব অ্যাডমিন তাদের ওয়েবসাইট ঠিক করার জন্য আমার অনুরোধ অগ্রাহ্য করছে, সুতরাং আমার অন্য কোনও উপায় ছিল না।
মিথ্যা রায়ান

4
আমার একটি ইউজ-কেস রয়েছে যেখানে আমার একটি ডিভিতে ত্রুটি বার্তা প্রদর্শন করতে হবে। ত্রুটি বার্তায় এইচটিএমএল এবং নিউলাইনগুলি থাকতে পারে। আমি এইচটিএমএল থেকে পালাতে এবং নতুনলাইনগুলি <br> এর সাথে প্রতিস্থাপন করতে চাই। তারপরে ফলাফলটি প্রদর্শনের জন্য একটি ডিভের মধ্যে রাখুন।
মোজেয়

উত্তর:


85

প্রতিস্থাপনটি সম্পাদন করতে আপনি কলব্যাক ফাংশনটি পাশ করার চেষ্টা করতে পারেন:

var tagsToReplace = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;'
};

function replaceTag(tag) {
    return tagsToReplace[tag] || tag;
}

function safe_tags_replace(str) {
    return str.replace(/[&<>]/g, replaceTag);
}

এখানে একটি পারফরম্যান্স পরীক্ষা: http://jsperf.com/encode-html-entities কল করার সাথে তুলনা করার জন্যreplace বারবার ফাংশনটি এবং দিমিত্রিজের প্রস্তাবিত DOM পদ্ধতি ব্যবহার করে ।

আপনার উপায়টি দ্রুত বলে মনে হচ্ছে ...

যদিও আপনার এটি দরকার?


4
পালানোর দরকার নেই >

6
প্রকৃতপক্ষে আপনি যদি এইচটিএমএল উপাদানটির বৈশিষ্ট্যে পালানো মানটি রেখে দেন তবে আপনাকে> প্রতীকটি এড়িয়ে চলতে হবে। অন্যথায় এটি এইচটিএমএল উপাদানটির জন্য ট্যাগটি ভেঙে ফেলবে।
জ্লাতিন জ্লাটভ

4
সাধারণ পাঠ্যে পালিয়ে যাওয়া চরিত্রগুলি বিরল। প্রয়োজনে কেবল প্রতিস্থাপনকে কল করা ভাল, যদি আপনি সর্বাধিক গতির যত্ন নিয়ে থাকেন:if (/[<>&"]/.test(str) { ... }
ভাইটালি

4
@ ক্যালাম: না। আমি মনে করি যে "কিছু ভুল হতে পারে" সে ক্ষেত্রে গণনা করতে আমি আগ্রহী নই (কমপক্ষে নয় কারণ এটি অপ্রত্যাশিত / ভুলে যাওয়া ঘটনা যা আপনাকে ক্ষতিগ্রস্থ করবে এবং আপনি যখন এটির বিষয়ে আশা করবেন তখন)। আমি মানগুলিতে কোডিং করতে আগ্রহী (তাই অপ্রত্যাশিত / ভুলে যাওয়া কেস সংজ্ঞা দিয়ে আপনাকে ক্ষতি করতে পারে না )। আমি জোর দিয়ে বলতে পারি না এটি কতটা গুরুত্বপূর্ণ। >এইচটিএমএল একটি বিশেষ চরিত্র, তাই এটি এড়ানোর। যে হিসাবে সহজ। :)
অরবিটে

4
@ লাইটনেসেসেসিনআরবিট এটি প্রাসঙ্গিক কারণ প্রশ্নটি হ'ল দ্রুততম পদ্ধতিটি কী। যদি >প্রতিস্থাপনটি এড়িয়ে যাওয়া সম্ভব হয় তবে এটি আরও দ্রুত করে তুলবে।
কল

105

আপনি এটি করতে পারেন এমন একটি উপায় এখানে:

var escape = document.createElement('textarea');
function escapeHTML(html) {
    escape.textContent = html;
    return escape.innerHTML;
}

function unescapeHTML(html) {
    escape.innerHTML = html;
    return escape.textContent;
}

এখানে একটি ডেমো আছে।


ডেমোটি নতুন করে তৈরি করা হয়েছে। এখানে একটি পূর্ণস্ক্রিন সংস্করণ রয়েছে: jsfiddle.net/Daniel_Hug/QPUEX/show/light
Web_Designer

13
কীভাবে / কীভাবে / কেন - নিশ্চিত নয় তবে এটি প্রতিভা।
রব_জেমস

4
দেখে মনে হচ্ছে এটি আক্ষরিক পাঠ্য থেকে রেহাই পাওয়ার জন্য পাঠ্যআরিয়া উপাদানটির বিদ্যমান কোডটি ব্যবহার করছে। খুব সুন্দর, আমি মনে করি এই ছোট্ট কৌশলটি অন্য একটি বাড়ি খুঁজে পেতে চলেছে।
আজাক্স

4
@ জাজকাত আমি সেই ফাংশনটি ব্যবহার করছি না। আমি যে অব্যাহতি পরিবর্তনশীলটি ব্যবহার করি, আমি তার উদাহরণটিতে নিজেকে সংজ্ঞায়িত করি।
ওয়েব_ডিজাইনার

4
তবে এটি কী সাদা স্থান হারাবে?
অ্যান্ড্রু

32

প্রোটোটাইপ ফাংশন হিসাবে মার্টিজানের পদ্ধতি:

String.prototype.escape = function() {
    var tagsToReplace = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;'
    };
    return this.replace(/[&<>]/g, function(tag) {
        return tagsToReplace[tag] || tag;
    });
};

var a = "<abc>";
var b = a.escape(); // "&lt;abc&gt;"

12
যোগ Stringএই এটি হওয়া উচিত পছন্দ escapeHtml যেহেতু এটি একটি সাধারণ একটি স্ট্রিং জন্য পলায়নের না। যে String.escapeHtmlসঠিক, কিন্তু String.escapeপ্রশ্ন উত্থাপন, "পালাবার কি জন্য?"
লরেন্স ডল

4
হ্যাঁ ভাল ধারণা। বিরোধগুলি এড়াতে আমি আজকাল প্রোটোটাইপ বাড়ানো থেকে সরে এসেছি moved
আরাম কোচার্যান

4
যদি আপনার ব্রাউজারে সিম্বলটির সমর্থন থাকে তবে আপনি স্ট্রিং-কী নেমস্পেসকে দূষিত করা এড়াতে এটি ব্যবহার করতে পারেন। var Escape = নতুন প্রতীক ("পালাতে"); স্ট্রিং.প্রোটোটাইপ [পলায়ন] = ফাংশন () {...}; "পাঠ্য" [পালানো] ();
আজাক্স

উদাহরণস্বরূপ প্লাস এক।
টিমো

13

দ্রুততম পদ্ধতিটি হ'ল:

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

এই পদ্ধতি প্রায় দ্বিগুন দ্রুত পদ্ধতি 'প্রতিস্থাপন' উপর ভিত্তি করে, চেয়ে দেখতে http://jsperf.com/htmlencoderegex/35

সূত্র: https://stackoverflow.com/a/17546215/698168


12

আরও দ্রুত / সংক্ষিপ্ত সমাধান হ'ল:

escaped = new Option(html).innerHTML

এটি জাভাস্ক্রিপ্টের কিছু অদ্ভুত অংশের সাথে সম্পর্কিত যার মাধ্যমে অপশন উপাদানটি এমন কোনও কনস্ট্রাক্টরকে ধরে রাখে যা এই ধরণের স্বয়ংক্রিয়ভাবে পালাতে পারে।

Https://github.com/jasonmoo/t.js/blob/master/t.js এর ক্রেডিট


4
ঝরঝরে ওয়ান-লাইনার তবে রেজেক্সের পরে সবচেয়ে ধীর পদ্ধতি । এছাড়াও, টেক্সট এখানে হোয়াইটস্পেস ছিনতাই থাকতে পারে, অনুযায়ী বৈশিষ্ট
ShortFuse

নোট করুন যে @ শর্টফিউজের "সবচেয়ে ধীরতম পদ্ধতি" লিঙ্কটি আমার সিস্টেমটি র‌্যামের বাইরে চলে গেছে (GB 6 জিবি নিখরচায়) এবং ফায়ারফক্স মনে হচ্ছে স্মৃতিশক্তি শেষ হওয়ার আগেই বরাদ্দ দেওয়া বন্ধ করে দেয় তাই আপত্তিজনক প্রক্রিয়াটি মেরে ফেলার পরিবর্তে লিনাক্স সেখানে বসে আপনাকে করতে দেয় একটি শক্ত শক্তি বন্ধ।
লু

11

AngularJS উত্স কোডটিতে কৌণিক-স্যানিটাইজ.জেএস এর ভিতরে একটি সংস্করণ রয়েছে ।

var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
    // Match everything outside of normal chars and " (quote character)
    NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
/**
 * Escapes all potentially dangerous characters, so that the
 * resulting string can be safely inserted into attribute or
 * element text.
 * @param value
 * @returns {string} escaped text
 */
function encodeEntities(value) {
  return value.
    replace(/&/g, '&amp;').
    replace(SURROGATE_PAIR_REGEXP, function(value) {
      var hi = value.charCodeAt(0);
      var low = value.charCodeAt(1);
      return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
    }).
    replace(NON_ALPHANUMERIC_REGEXP, function(value) {
      return '&#' + value.charCodeAt(0) + ';';
    }).
    replace(/</g, '&lt;').
    replace(/>/g, '&gt;');
}

4
বাহ, সেই অ-আলফানাম রেজেক্স তীব্র। আমি মনে করি না | মত প্রকাশের প্রয়োজন যদিও।
আজাক্স

9

সমস্ত-ইন-ওয়ান স্ক্রিপ্ট:

// HTML entities Encode/Decode

function htmlspecialchars(str) {
    var map = {
        "&": "&amp;",
        "<": "&lt;",
        ">": "&gt;",
        "\"": "&quot;",
        "'": "&#39;" // ' -> &apos; for XML only
    };
    return str.replace(/[&<>"']/g, function(m) { return map[m]; });
}
function htmlspecialchars_decode(str) {
    var map = {
        "&amp;": "&",
        "&lt;": "<",
        "&gt;": ">",
        "&quot;": "\"",
        "&#39;": "'"
    };
    return str.replace(/(&amp;|&lt;|&gt;|&quot;|&#39;)/g, function(m) { return map[m]; });
}
function htmlentities(str) {
    var textarea = document.createElement("textarea");
    textarea.innerHTML = str;
    return textarea.innerHTML;
}
function htmlentities_decode(str) {
    var textarea = document.createElement("textarea");
    textarea.innerHTML = str;
    return textarea.value;
}

http://pastebin.com/JGCVs0Ts


আমি ডাউনভিট করিনি, তবে সমস্ত রেজেক্স স্টাইল প্রতিস্থাপন ইউনিকোড এনকোড করতে ব্যর্থ হবে ... সুতরাং, বিদেশী ভাষা ব্যবহার করা যে কেউ হতাশ হতে চলেছে। উপরে উল্লিখিত <টেক্সটের </a> কৌশলটি খুব দুর্দান্ত এবং দ্রুত এবং সুরক্ষার সাথে সবকিছু পরিচালনা করে।
আজাক্স

রেজেক্সটি আমার জন্য বেশ কয়েকটি নন-ল্যাটিন ইউনিকোড অক্ষর দিয়ে কাজ করে। আমি অন্য কিছু আশা করব না। আপনি কীভাবে মনে করেন এটি কাজ করবে না? আপনি কি সিঙ্গল-বাইট কোডপেজের কথা ভাবছেন যা এইচটিএমএল সত্ত্বার প্রয়োজন? তৃতীয় এবং চতুর্থ ফাংশনটি এটাই, এবং স্পষ্টভাবে 1 ম এবং দ্বিতীয়টি নয়। আমি পার্থক্য পছন্দ করি।
ygoe

@ লোনলিপিক্সেল আমি মনে করি না যে তিনি আপনার মন্তব্যটি উল্লেখ করবেন যদি আপনি তার উল্লেখ না করেন ("কেবলমাত্র একটি অতিরিক্ত ব্যবহারকারীকে অবহিত করা যেতে পারে; পোস্টের মালিককে সর্বদা অবহিত করা হবে")
ব্যাপটেক্স

আমি জানতাম না লক্ষ্যযুক্ত বিজ্ঞপ্তিগুলি মোটেই বিদ্যমান। @ আজাক্স দয়া করে উপরে আমার মন্তব্য দেখুন।
ygoe

@ লোনলিপিক্সেল এখনই দেখছি। কিছু কারণে আমি এই উত্তরে একটি টেক্সেরিয়া স্টাইল প্রতিস্থাপন আছে বলে মনে করি না। আমি প্রকৃতপক্ষে, ডাবল কোডেপয়েন্ট পয়েন্ট বড় বড় ইউনিকোড মান, ম্যান্ডারিনের মতোই ভাবছিলাম। আমি বলতে চাইছি, একটি রেগেক্সকে যথেষ্ট স্মার্ট করা সম্ভব হবে, তবে আপনি যখন ব্রাউজার বিক্রেতারা নিতে পারেন সেই শর্টকাটগুলির দিকে তাকান, আমি টেক্সারিয়া আরও দ্রুত হবে (পুরোপুরি পারদর্শী রেজেক্সের তুলনায়) বেশ ভালই বোধ করব। কেউ কি এই উত্তরে একটি মানদণ্ড পোস্ট করেছে? আমি কসম খেয়েছিলাম আমি একটি দেখেছি।
আজাক্স

2

function encode(r) {
  return r.replace(/[\x26\x0A\x3c\x3e\x22\x27]/g, function(r) {
	return "&#" + r.charCodeAt(0) + ";";
  });
}

test.value=encode('How to encode\nonly html tags &<>\'" nice & fast!');

/*
 \x26 is &ampersand (it has to be first),
 \x0A is newline,
 \x22 is ",
 \x27 is ',
 \x3c is <,
 \x3e is >
*/
<textarea id=test rows=11 cols=55>www.WHAK.com</textarea>


1

আমি গতি সম্পর্কে পুরোপুরি নিশ্চিত নই, তবে আপনি যদি সরলতার সন্ধান করেন তবে আমি লোডাশ / আন্ডারস্কোর এস্কেপ ফাংশনটি ব্যবহার করার পরামর্শ দেব ।


0

" চিহ্ন ( জাভাস্ক্রিপ্টে ব্যবহার করে ) পরিচালনা করার সাথে মার্টিজন এর পদ্ধতিটি একক ফাংশন হিসাবে :

function escapeHTML(html) {
    var fn=function(tag) {
        var charsToReplace = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&#34;'
        };
        return charsToReplace[tag] || tag;
    }
    return html.replace(/[&<>"]/g, fn);
}

0

আমি XMLSerializerগাদা যোগ করব । এটি কোনও অবজেক্ট ক্যাচিং ব্যবহার না করে দ্রুততম ফলাফল সরবরাহ করে (সিরিয়ালাইজারে বা টেক্সট নোডে নয়)।

function serializeTextNode(text) {
  return new XMLSerializer().serializeToString(document.createTextNode(text));
}

যুক্ত বোনাসটি হ'ল এটি এমন বৈশিষ্ট্যগুলিকে সমর্থন করে যা পাঠ্য নোডের চেয়ে আলাদাভাবে ক্রমিকায়িত হয়:

function serializeAttributeValue(value) {
  const attr = document.createAttribute('a');
  attr.value = value;
  return new XMLSerializer().serializeToString(attr);
}

পাঠ্য নোড এবং বৈশিষ্ট্যযুক্ত মান উভয়ের জন্যই অনুমানটি যাচাই করে এটি কী প্রতিস্থাপন করছে তা দেখতে পাচ্ছেন । সম্পূর্ণ ডকুমেন্টেশনে আরও নোডের ধরণ রয়েছে তবে ধারণাটি একই।

পারফরম্যান্সের ক্ষেত্রে, যখন ক্যাশেড না হয় তখন এটি সবচেয়ে দ্রুত। আপনি যখন innerHTMLক্যাচিংয়ের অনুমতি দিচ্ছেন, তারপরে একটি শিশু পাঠ্য নোডের সাথে একটি এইচটিএমলেমেন্টে কল করা সবচেয়ে দ্রুত। Regex সবচেয়ে ধীর হবে (অন্যান্য মন্তব্য দ্বারা প্রমাণিত)। অবশ্যই, এক্সএমএলসিরালাইজার অন্যান্য ব্রাউজারগুলিতে দ্রুততর হতে পারে, তবে আমার (সীমাবদ্ধ) পরীক্ষায়, একটি innerHTMLদ্রুততম।


দ্রুততম একক লাইন:

new XMLSerializer().serializeToString(document.createTextNode(text));

ক্যাচিংয়ের সাথে দ্রুততম:

const cachedElementParent = document.createElement('div');
const cachedChildTextNode = document.createTextNode('');
cachedElementParent.appendChild(cachedChildTextNode);

function serializeTextNode(text) {
  cachedChildTextNode.nodeValue = text;
  return cachedElementParent.innerHTML;
}

https://jsperf.com/htmlentityencode/1


-3

4
সেই কি কিছু সম্পূর্ণরূপে সম্পর্কহীন
ক্যালাম

4
"পুরোপুরি" শব্দের সবচেয়ে বড় আপত্তি সম্ভবত আমি শুনেছি। উদাহরণস্বরূপ, মূল বিষয়ের প্রশ্নের সাথে সম্পর্কিত, এটি এইচটিএমএল ট্যাগ নির্বিশেষে কোনও এইচটিএমএল স্ট্রিং (স্পষ্টতই কিছু ধরণের স্টোরেজ কারণে) ডিকোড করতে ব্যবহার করা যেতে পারে এবং প্রয়োজনে এবং প্রয়োজনে সহজেই আবার এইচটিএমএলে ফিরে এনকোড করা যায়।
সানক্যাট 100
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.