เข้ารหัสเอนทิตี html ในจาวาสคริปต์


100

ฉันทำงานใน CMS ซึ่งอนุญาตให้ผู้ใช้ป้อนเนื้อหาได้ ปัญหาคือเมื่อเพิ่มสัญลักษณ์®อาจแสดงผลได้ไม่ดีในทุกเบราว์เซอร์ ฉันต้องการตั้งค่ารายการสัญลักษณ์ที่ต้องค้นหาจากนั้นแปลงเป็นเอนทิตี html ที่เกี่ยวข้อง ตัวอย่างเช่น

® => ®
& => &
© => ©
™ =>™

หลังจากการแปลงจะต้องมีการรวม<sup>แท็กซึ่งทำให้เกิดสิ่งนี้:

® => <sup>&reg;</sup>

เนื่องจากจำเป็นต้องมีขนาดตัวอักษรและรูปแบบการขยายที่เฉพาะเจาะจง:

sup { font-size: 0.6em; padding-top: 0.2em; }

JavaScript จะเป็นแบบนี้หรือไม่?

var regs = document.querySelectorAll('®');
  for ( var i = 0, l = imgs.length; i < l; ++i ) {
  var [?] = regs[i];
  var [?] = document.createElement('sup');
  img.parentNode.insertBefore([?]);
  div.appendChild([?]);
}

โดยที่ "[?]" หมายความว่ามีบางอย่างที่ฉันไม่แน่ใจ

รายละเอียดเพิ่มเติม:

  • ฉันต้องการทำสิ่งนี้ด้วย JavaScript บริสุทธิ์ไม่ใช่สิ่งที่ต้องใช้ไลบรารีเช่น jQuery ขอบคุณ
  • แบ็กเอนด์คือ Ruby
  • ใช้ RefineryCMS ซึ่งสร้างด้วย Ruby on Rails

แบ็กเอนด์ของคุณคืออะไร? ถ้าเป็น php มีฟังก์ชั่นที่จะดูแลคุณและฉันแน่ใจว่าภาษาอื่น ๆ ก็มีเช่นกัน นอกจากนี้ Google: developwithstyle.com/articles/2010/06/29/…
Chris Baker

5
ทางออกที่ดีกว่าคือการยอมรับและส่งออกข้อความที่เข้ารหัส UTF-8 ทุกเบราว์เซอร์ที่ใช้ในปัจจุบันรองรับ UTF-8 ในด้าน HTML คุณต้องการเพิ่มลงaccept-charset="UTF-8"ใน<form>แท็กของคุณ บนเซิร์ฟเวอร์คุณต้องการตรวจสอบให้แน่ใจว่าเอาต์พุตของคุณเข้ารหัส UTF-8 และเว็บเซิร์ฟเวอร์ของคุณบอกเบราว์เซอร์ว่าเป็น (ผ่านContent-Typeส่วนหัว) ดูrentzsch.tumblr.com/post/9133498042/…หากคุณทำทุกอย่างแล้วและเบราว์เซอร์แสดงอักขระไม่ถูกต้องการแทนที่อักขระด้วยเอนทิตีจะไม่สร้างความแตกต่าง
Paul D.Waite

@Chris ทำงานใน CMS ที่สร้างด้วย Ruby on Rails
JGallardo

การเปลี่ยนอักขระเป็นการอ้างอิงเอนทิตี HTML ใน JavaScript ฝั่งไคลเอ็นต์เป็นเรื่องผิดเนื่องจาก JavaScript ฝั่งไคลเอ็นต์ทำงานบน DOM โดยที่ไม่มีเอนทิตี การห่อ“ ®” ลงในsupองค์ประกอบมีแนวโน้มที่จะทำให้เกิดปัญหามากกว่าที่จะแก้ไขได้เนื่องจากในแบบอักษรจำนวนมาก“ ®” มีขนาดเล็กและอยู่ในตำแหน่งตัวห้อยดังนั้นคุณจึงลดขนาดลงจนไม่สามารถจดจำได้
Jukka K. Korpela

@ JukkaK.Korpela ดังนั้นเมื่อพิจารณาว่าฉันต้องระบุว่าเอนทิตี html บางรายการจะแสดงไม่ถูกต้องคุณจะจัดการกับมันอย่างไร และการรวมเข้าด้วยกัน<sup>ก็ไม่ใช่ปัญหาเนื่องจากฉันได้ทดสอบฟอนต์เฉพาะที่ใช้สำหรับบล็อกโพสต์ แต่นั่นเป็นจุดที่ดีที่ควรพิจารณา
JGallardo

คำตอบ:


176

คุณสามารถใช้ regex เพื่อแทนที่อักขระใด ๆ ในช่วงยูนิโค้ดที่กำหนดด้วยเอนทิตี html ที่เทียบเท่า รหัสจะมีลักษณะดังนี้:

var encodedStr = rawStr.replace(/[\u00A0-\u9999<>\&]/g, function(i) {
   return '&#'+i.charCodeAt(0)+';';
});

รหัสนี้จะแทนที่ตัวอักษรทั้งหมดในช่วงที่กำหนด (Unicode 00A0 - 9999 เช่นเดียวกับเครื่องหมายมากขึ้นและน้อยกว่า) กับ HTML เทียบเท่านิติบุคคลของพวกเขาซึ่งเป็นเพียง&#nnn;ที่nnnเป็นค่า Unicode charCodeAtที่เราได้รับจาก

ดูการใช้งานจริงที่นี่: http://jsfiddle.net/E3EqX/13/ (ตัวอย่างนี้ใช้ jQuery สำหรับตัวเลือกองค์ประกอบที่ใช้ในตัวอย่างโค้ดฐานด้านบนไม่ใช้ jQuery)

การแปลงเหล่านี้ไม่ได้ช่วยแก้ปัญหาทั้งหมด - ตรวจสอบให้แน่ใจว่าคุณใช้การเข้ารหัสอักขระ UTF8 ตรวจสอบให้แน่ใจว่าฐานข้อมูลของคุณจัดเก็บสตริงใน UTF8 คุณยังอาจเห็นกรณีที่อักขระแสดงไม่ถูกต้องทั้งนี้ขึ้นอยู่กับการกำหนดค่าแบบอักษรของระบบและปัญหาอื่น ๆ ที่ไม่สามารถควบคุมได้

เอกสารประกอบ


ขอบคุณมากสำหรับ jsfiddle เพื่อนำสิ่งนี้ไปใช้ ฉันสามารถเพิ่มสิ่งนี้ลงใน.jsไฟล์ของฉันและเพิ่มสิ่งอื่น ๆ เพื่อห่อด้วย<sup>?
JGallardo

2
@JGallardo ฉันกำลังเขียนตัวอย่างเล็ก ๆ น้อย ๆ เพื่อที่จะเพิ่มsupแท็ก (tag หรืออื่น ๆ ) และมันก็มีอยู่ในฟังก์ชั่น: jsfiddle.net/E3EqX/4 ในการใช้งานคุณต้องคัดลอกฟังก์ชัน "encodeAndWrap" ไปยังโครงการของคุณ
Chris Baker

1
@Chris ขอบคุณสำหรับข้อมูลโค้ดที่เป็นระเบียบแม้ว่าจะมีข้อบกพร่องอย่างหนึ่ง: "[\ u00A0- \ u99999]" ไม่ได้ทำในสิ่งที่คุณคาดหวัง แต่จะเท่ากับ "[\ u00A0- \ u9999] | 9 "- คือ. อักขระ "9" จะถูกแทนที่ด้วยเอนทิตี HTML อย่างไม่ถูกต้องเช่นกัน คุณสามารถลองในซอได้เช่นกัน ฉันจะแนะนำวิธีแก้ไขสำหรับคำตอบ
SB

@SB ขอบคุณสำหรับบันทึกนั้นฉันยังต้องโหวตอนุมัติขั้นสุดท้าย :)
Chris Baker

1
แม้ว่าฉันจะยอมรับว่าคำตอบของ @mathias Bynens นั้นสมบูรณ์กว่า แต่โซลูชันของเขาคือ 84KB และนั่นทำให้ฉันมองหาทางเลือกอื่นต่อไป ดูเหมือนว่า OK-ish แต่อาจรวมถึง charCodes <65 และระหว่าง> 90 && <97?
Florian Mertens

62

คำตอบที่ยอมรับในปัจจุบันมีหลายประเด็น โพสต์นี้อธิบายถึงพวกเขาและนำเสนอโซลูชันที่มีประสิทธิภาพมากขึ้น โซลูชันที่แนะนำในคำตอบนั้นก่อนหน้านี้มี:

var encodedStr = rawStr.replace(/[\u00A0-\u9999<>\&]/gim, function(i) {
  return '&#' + i.charCodeAt(0) + ';';
});

iธงซ้ำซ้อนเนื่องจากไม่มีสัญลักษณ์ Unicode ในช่วงจาก U + 00A0 เพื่อ U + 9999 มีพิมพ์ใหญ่ / พิมพ์เล็กตัวแปรที่อยู่นอกช่วงเดียวกันกับที่

mธงซ้ำซ้อนเพราะ^หรือ$ไม่ได้ใช้ในการแสดงออกปกติ

ทำไมช่วง U + 00A0 ถึง U + 9999 ดูเหมือนตามอำเภอใจ

อย่างไรก็ตามสำหรับโซลูชันที่เข้ารหัสทั้งหมดอย่างถูกต้องยกเว้นสัญลักษณ์ ASCII ที่ปลอดภัยและพิมพ์ได้ในอินพุต (รวมถึงสัญลักษณ์ดาว!) และใช้การอ้างอิงอักขระที่มีชื่อทั้งหมด (ไม่ใช่เฉพาะใน HTML4) ให้ใช้ไลบรารีhe (ข้อจำกัดความรับผิดชอบ: ไลบรารีนี้เป็นของฉัน ). จาก README:

เขา (สำหรับ“ เอนทิตี HTML”) เป็นตัวเข้ารหัส / ตัวถอดรหัสเอนทิตี HTML ที่มีประสิทธิภาพซึ่งเขียนด้วย JavaScript สนับสนุนการอ้างอิงอักขระที่มีชื่อมาตรฐานทั้งหมดตาม HTMLจัดการเครื่องหมายแอมเพอร์แซนด์ที่ไม่ชัดเจนและกรณีขอบอื่น ๆเช่นเดียวกับเบราว์เซอร์มีชุดทดสอบที่กว้างขวางและ - ตรงกันข้ามกับโซลูชัน JavaScript อื่น ๆ อีกมากมาย - เขาจัดการสัญลักษณ์ Astral Unicode ได้ดี มีการสาธิตออนไลน์

ดูคำตอบ Stack Overflow ที่เกี่ยวข้องด้วย


12
นอกจากนี้ห้องสมุด HE คือ ... 84KB! Autch ... ลองดาวน์โหลดบนโทรศัพท์มือถือผ่านการเชื่อมต่อที่น้อยกว่า ต้องมีการประนีประนอมที่ไหนสักแห่ง ..
Florian Mertens

1
@FlorianMertens หลังจาก minifying + gzip เขาคือ ~ 24 KB ยังคงมีขนาดใหญ่ แต่ในตอนท้ายของวันหากคุณต้องการถอดรหัสเอนทิตี HTML อย่างถูกต้องคุณจะต้องใช้ข้อมูลทั้งหมดในนั้น - ไม่มีทางหลีกเลี่ยงได้ หากคุณสามารถหาวิธีทำให้ห้องสมุดเล็กลงโดยไม่ส่งผลกระทบต่อประสิทธิภาพโปรดส่งคำขอดึง
Mathias Bynens

2
@MathiasBynens ไม่ต้องสงสัยเลยว่าห้องสมุดของคุณดี แต่คุณสามารถใช้ช่องแสดงความคิดเห็นเพื่อเน้นปัญหาในคำตอบที่ยอมรับและโปรดส่งคำตอบที่ปรับปรุงแล้วของคุณในบล็อกโค้ด
diEcho

3
@drzaus รูปภาพสามารถหลีกเลี่ยงได้เนื่องจากมีขนาดใหญ่เนื่องจากเก็บข้อมูลได้มากและข้อมูลที่บีบอัดน้อยจะถอดรหัสได้เร็วขึ้น อย่างไรก็ตามรหัสโปรแกรมแตกต่างกันบ่อยครั้งที่มีการเพิ่มไลบรารีทั้งหมดและมีการใช้งานเพียงเล็กน้อย บางครั้งรหัสของห้องสมุดจะมีจำนวนบรรทัดมากกว่ารหัสของคุณเอง! มีเพียงไม่กี่คนที่จะต้องค้นหา / แก้ไขปัญหา lib และส่งรายงานข้อผิดพลาด (หรือแม้แต่อัปเดต lib) ดังนั้นการรั่วไหลของหน่วยความจำหรือปัญหาอื่น ๆ อาจยังคงมีอยู่ในซอฟต์แวร์ที่มี libs จำนวนมากที่มีรหัสที่ไม่ได้ตรวจ หากมีคนต้องการเข้ารหัส / หลีกเลี่ยงตัวอักษร html ที่ไม่ปลอดภัยจำเป็นต้องใช้เพียงไม่กี่บรรทัดไม่ใช่ 80kb
bryc

1
@MarcoKlein ใช่ฉันอธิบายในโพสต์ของฉัน แน่นอนว่ามันเป็นปัญหาที่ข้อมูลโค้ด buggy ต้องทนทุกข์ทรมาน วิธีแก้ปัญหาที่ฉันชี้ไปไม่มีปัญหานั้น (ดู“ รวมสัญลักษณ์ดาว!”)
Mathias Bynens

29

ฉันมีปัญหาเดียวกันและสร้าง 2 ฟังก์ชันเพื่อสร้างเอนทิตีและแปลกลับเป็นอักขระปกติ วิธีการต่อไปนี้จะแปลสตริงใด ๆ เป็นเอนทิตี HTML และกลับมาที่ String ต้นแบบ

/**
 * Convert a string to HTML entities
 */
String.prototype.toHtmlEntities = function() {
    return this.replace(/./gm, function(s) {
        // return "&#" + s.charCodeAt(0) + ";";
        return (s.match(/[a-z0-9\s]+/i)) ? s : "&#" + s.charCodeAt(0) + ";";
    });
};

/**
 * Create string from HTML entities
 */
String.fromHtmlEntities = function(string) {
    return (string+"").replace(/&#\d+;/gm,function(s) {
        return String.fromCharCode(s.match(/\d+/gm)[0]);
    })
};

จากนั้นคุณสามารถใช้งานได้ดังต่อไปนี้:

var str = "Test´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æøπ£¨ ƒ™en tést".toHtmlEntities();
console.log("Entities:", str);
console.log("String:", String.fromHtmlEntities(str));

เอาต์พุตในคอนโซล:

Entities: &#68;&#105;&#116;&#32;&#105;&#115;&#32;&#101;&#180;&#8224;&#174;&#165;&#168;&#169;&#729;&#8747;&#248;&#8230;&#710;&#402;&#8710;&#247;&#8721;&#8482;&#402;&#8710;&#230;&#248;&#960;&#163;&#168;&#160;&#402;&#8482;&#101;&#110;&#32;&#116;&#163;&#101;&#233;&#115;&#116;
String: Dit is e´†®¥¨©˙∫ø…ˆƒ∆÷∑™ƒ∆æøπ£¨ ƒ™en t£eést 

โซลูชันนี้ใช้ได้กับ tvOS ดังนั้นจึงสามารถแก้ปัญหาการเข้ารหัสได้ดีในทุกกรณี
loretoparisi

4
มันไม่สุดโต่งไปหน่อยเหรอ? คุณกำลังแปลงทุกอย่างเป็นเอนทิตี HTML แม้แต่อักขระที่ "ปลอดภัย" เช่น "abc", "123" ... แม้แต่ช่องว่าง
AJPerez

1
นี่เป็นคำตอบที่ไม่ดี เอกสารบนเว็บ 50% ขึ้นไปมีภาษาละติน 1 เป็นส่วนใหญ่กับ utf-8 การเข้ารหัสอักขระที่ปลอดภัยของคุณจะเพิ่มขนาดขึ้น 500% เป็น 600% โดยไม่มีข้อได้เปรียบใด ๆ
HoldOffHunger

โปรดอธิบายวัตถุประสงค์ของการmปรับเปลี่ยนรูปแบบในรูปแบบที่ไม่มีจุดยึด คุณหมายถึงใช้sสำหรับรูปแบบที่มีจุด?
mickmackusa

19

หากไม่มีไลบรารีใด ๆ หากคุณไม่จำเป็นต้องรองรับ IE <9 คุณสามารถสร้างองค์ประกอบ html และตั้งค่าเนื้อหาด้วยNode.textContent :

var str = "<this is not a tag>";
var p = document.createElement("p");
p.textContent = str;
var converted = p.innerHTML;

นี่คือตัวอย่าง: https://jsfiddle.net/1erdhehv/


2
ทำไมไม่ใช้ innerText แทน textContent?
ริก

@ ริกให้เอกสาร MDN สำหรับ textContent ที่เชื่อมโยงในคำตอบ การอ้างถึง "textContent และ HTMLElement.innerText นั้นสับสนได้ง่าย แต่คุณสมบัติทั้งสองแตกต่างกันในลักษณะที่สำคัญ "
Adarsha

17

คุณสามารถใช้สิ่งนี้

var escapeChars = {
  '¢' : 'cent',
  '£' : 'pound',
  '¥' : 'yen',
  '€': 'euro',
  '©' :'copy',
  '®' : 'reg',
  '<' : 'lt',
  '>' : 'gt',
  '"' : 'quot',
  '&' : 'amp',
  '\'' : '#39'
};

var regexString = '[';
for(var key in escapeChars) {
  regexString += key;
}
regexString += ']';

var regex = new RegExp( regexString, 'g');

function escapeHTML(str) {
  return str.replace(regex, function(m) {
    return '&' + escapeChars[m] + ';';
  });
};

https://github.com/epeli/underscore.string/blob/master/escapeHTML.js

var htmlEntities = {
    nbsp: ' ',
    cent: '¢',
    pound: '£',
    yen: '¥',
    euro: '€',
    copy: '©',
    reg: '®',
    lt: '<',
    gt: '>',
    quot: '"',
    amp: '&',
    apos: '\''
};

function unescapeHTML(str) {
    return str.replace(/\&([^;]+);/g, function (entity, entityCode) {
        var match;

        if (entityCode in htmlEntities) {
            return htmlEntities[entityCode];
            /*eslint no-cond-assign: 0*/
        } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) {
            return String.fromCharCode(parseInt(match[1], 16));
            /*eslint no-cond-assign: 0*/
        } else if (match = entityCode.match(/^#(\d+)$/)) {
            return String.fromCharCode(~~match[1]);
        } else {
            return entity;
        }
    });
};

4
การเพิ่มชุดย่อยของอักขระที่เข้ารหัสแบบสุ่มด้วยตนเองมีแนวโน้มที่จะเก็บปัญหาไว้สำหรับตัวคุณเองและเพื่อนร่วมงานของคุณ ควรมีหน่วยงานเดียวที่ควรเข้ารหัสอักขระอาจเป็นเบราว์เซอร์หรือไม่ได้ไลบรารีเฉพาะที่น่าจะครอบคลุมและคงไว้
user234461

เยี่ยมมาก @ user234461 หากใครพบว่าผู้มีอำนาจเพียงคนเดียวคนที่มีความคิดอยากรู้อยากเห็น (เช่นฉัน) จะต้องรู้!
idungotnosn

7

หากคุณต้องการหลีกเลี่ยงการเข้ารหัสเอนทิตี html มากกว่าหนึ่งครั้ง

function encodeHTML(str){
    return str.replace(/([\u00A0-\u9999<>&])(.|$)/g, function(full, char, next) {
      if(char !== '&' || next !== '#'){
        if(/[\u00A0-\u9999<>&]/.test(next))
          next = '&#' + next.charCodeAt(0) + ';';

        return '&#' + char.charCodeAt(0) + ';' + next;
      }

      return full;
    });
}

function decodeHTML(str){
    return str.replace(/&#([0-9]+);/g, function(full, int) {
        return String.fromCharCode(parseInt(int));
    });
}

# ตัวอย่าง

var text = "<a>Content &#169; <#>&<&#># </a>";

text = encodeHTML(text);
console.log("Encode 1 times: " + text);

// &#60;a&#62;Content &#169; &#60;#&#62;&#38;&#60;&#38;#&#62;# &#60;/a&#62;

text = encodeHTML(text);
console.log("Encode 2 times: " + text);

// &#60;a&#62;Content &#169; &#60;#&#62;&#38;&#60;&#38;#&#62;# &#60;/a&#62;

text = decodeHTML(text);
console.log("Decoded: " + text);

// <a>Content © <#>&<&#># </a>

สิ่งนี้มีประโยชน์ก็ต่อเมื่อคุณมีข้อความที่ใช้ Escape แบบผสมบางส่วนเพื่อเริ่มต้นด้วยและจะแนะนำข้อบกพร่องเนื่องจากไม่สามารถเข้ารหัสสตริงทั้งหมดได้อย่างถูกต้อง: <#>จะออกมาเป็น<#&#62;
Rick

@ ริกขอบคุณที่แจ้งให้ทราบเกี่ยวกับเรื่องนี้ฉันได้อัปเดตคำตอบเพื่อให้ดีขึ้น
StefansArya

4

อักขระพิเศษ HTML และ ESCAPE CODES

อักขระที่สงวนไว้จะต้องหลีกเลี่ยงโดย HTML: เราสามารถใช้อักขระ Escape เพื่อแสดงอักขระ Unicode [เช่น & - U + 00026] ใน HTML, XHTML หรือ XML โดยใช้อักขระ ASCII เท่านั้น อักขระตัวเลขการอ้างอิง [ Ex: ampersand (&) - &#38;] และชื่ออ้างอิงตัว [Ex: &amp;] character escape used in markupเป็นประเภทของ


เอนทิตีที่กำหนดไว้ล่วงหน้า

    Original Character     XML entity replacement    XML numeric replacement  
                  <                                    &lt;                                           &#60;                    
                  >                                     &gt;                                         &#62;                    
                  "                                     &quot;                                      &#34;                    
                  &                                   &amp;                                       &#38;                    
                   '                                    &apos;                                      &#39;                    

หากต้องการแสดงแท็ก HTML เป็นรูปแบบปกติในหน้าเว็บของเราใช้<pre>, <code>แท็กหรือเราสามารถหลบหนีพวกเขา หนีสตริงโดยการแทนที่ด้วยการเกิดขึ้นใด ๆ ของ"&"ตัวละครโดยสตริง"&amp;"และเหตุการณ์ใด ๆ ของตัวละครโดยสตริง">" "&gt;"เช่น:stackoverflow post

function escapeCharEntities() {
    var map = {
        "&": "&amp;",
        "<": "&lt;",
        ">": "&gt;",
        "\"": "&quot;",
        "'": "&apos;"
    };
    return map;
}

var mapkeys = '', mapvalues = '';
var html = {
    encodeRex : function () {
        return  new RegExp(mapkeys, 'g'); // "[&<>"']"
    }, 
    decodeRex : function () {
        return  new RegExp(mapvalues, 'g'); // "(&amp;|&lt;|&gt;|&quot;|&apos;)"
    },
    encodeMap : JSON.parse( JSON.stringify( escapeCharEntities () ) ), // json = {&: "&amp;", <: "&lt;", >: "&gt;", ": "&quot;", ': "&apos;"}
    decodeMap : JSON.parse( JSON.stringify( swapJsonKeyValues( escapeCharEntities () ) ) ),
    encode : function ( str ) {
        var encodeRexs = html.encodeRex();
        console.log('Encode Rex: ', encodeRexs); // /[&<>"']/gm
        return str.replace(encodeRexs, function(m) { console.log('Encode M: ', m); return html.encodeMap[m]; }); // m = < " > SpecialChars
    },
    decode : function ( str ) {
        var decodeRexs = html.decodeRex();
        console.log('Decode Rex: ', decodeRexs); // /(&amp;|&lt;|&gt;|&quot;|&apos;)/g
        return str.replace(decodeRexs, function(m) { console.log('Decode M: ', m); return html.decodeMap[m]; }); // m = &lt; &quot; &gt;
    }
};

function swapJsonKeyValues ( json ) {
    var count = Object.keys( json ).length;
    var obj = {};
    var keys = '[', val = '(', keysCount = 1;
    for(var key in json) {
        if ( json.hasOwnProperty( key ) ) {
            obj[ json[ key ] ] = key;
            keys += key;
            if( keysCount < count ) {
                val += json[ key ]+'|';
            } else {
                val += json[ key ];
            }
            keysCount++;
        }
    }
    keys += ']';    val  += ')';
    console.log( keys, ' == ', val);
    mapkeys = keys;
    mapvalues = val;
    return obj;
}

console.log('Encode: ', html.encode('<input type="password" name="password" value=""/>') ); 
console.log('Decode: ', html.decode(html.encode('<input type="password" name="password" value=""/>')) );

O/P:
Encode:  &lt;input type=&quot;password&quot; name=&quot;password&quot; value=&quot;&quot;/&gt;
Decode:  <input type="password" name="password" value=""/>

เหมาะสำหรับการเพิ่มซอร์สโค้ด html ในรูปแบบ Json ลงในสตริง iframe srcdoc
Nime Cloud

ซึ่งไม่รวมถึง®ดังนั้นจึงไม่ช่วย OP นอกจากนี้ JS นี้ยังซับซ้อนกว่าโซลูชันอื่น ๆ มากแม้แต่โซลูชันที่ใช้เพียงการแมปสั้น ๆ เช่นนี้ swapJsonKeyValues ​​มีชื่อไม่ดีเนื่องจากต้องมีผลข้างเคียง (การกำหนด mapkeys และ mapvalues)
Rick

@mickmackusa ฉันได้อัปเดตโพสต์ด้วยค่าดีบัก mเก็บอักขระพิเศษของสตริงอินพุต
Yash

หากผิดพลาดประการใดในกระทู้. ดังนั้นโปรดพยายามแก้ไขโพสต์และแสดงความคิดเห็น
Yash

3
var htmlEntities = [
            {regex:/&/g,entity:'&amp;'},
            {regex:/>/g,entity:'&gt;'},
            {regex:/</g,entity:'&lt;'},
            {regex:/"/g,entity:'&quot;'},
            {regex:/á/g,entity:'&aacute;'},
            {regex:/é/g,entity:'&eacute;'},
            {regex:/í/g,entity:'&iacute;'},
            {regex:/ó/g,entity:'&oacute;'},
            {regex:/ú/g,entity:'&uacute;'}
        ];

total = <some string value>

for(v in htmlEntities){
    total = total.replace(htmlEntities[v].regex, htmlEntities[v].entity);
}

โซลูชันอาร์เรย์


3
โปรดอธิบายว่าวิธีนี้แก้ปัญหาด้วยวิธีที่ดีกว่าข้างต้นอย่างไร เมื่อมองอย่างรวดเร็วดูเหมือนว่าโซลูชันนี้จะช้าลงเนื่องจากมีการปรับเปลี่ยนสตริงในการส่งผ่านหลายครั้งแทนที่จะเป็นทั้งหมดในครั้งเดียว อย่างไรก็ตามฉันอาจจะไม่ถูกต้อง ไม่ว่าจะด้วยวิธีใดคุณต้องสำรองข้อมูลที่คุณโพสต์พร้อมคำอธิบาย
Jack Giffin

อีกทางเลือกหนึ่งคือคุณสามารถใช้ regex ได้โดยตรงจากอาร์เรย์ ... : D
Cesar De la Cruz

นี่คือ regex หนึ่งรายการสำหรับแต่ละอักขระ (สำหรับ v in .... ) หากคุณต้องการครอบคลุม UTF-8 ทั้งหมดนี่คือ 65,000 regex และ 65,000 บรรทัดของการดำเนินการ
HoldOffHunger

2
ฉันสนใจแค่การแปลงอักขระสามตัวเป็นเอนทิตีดังนั้นคำตอบนี้ดีกว่าในกรณีของฉันและฉันดีใจที่ได้มาที่นี่
Drew

2

หากคุณใช้ jQuery html()ลอง

$('<div>').text('<script>alert("gotcha!")</script>').html()
// "&lt;script&gt;alert("gotcha!")&lt;/script&gt;"

โหนดข้อความในหน่วยความจำถูกสร้างอินสแตนซ์และhtml()ถูกเรียกใช้

มันน่าเกลียดมันเสียหน่วยความจำไปหน่อยและฉันไม่รู้ว่ามันละเอียดพอ ๆ กับheไลบรารีหรือไม่ แต่ถ้าคุณใช้ jQuery อยู่แล้วนี่อาจเป็นตัวเลือกสำหรับคุณ

นำมาจากบล็อกโพสต์เข้ารหัสเอนทิตี HTML ด้วย jQueryโดย Felix Geisendörfer


3
เพื่อหลีกเลี่ยงการสร้างอินสแตนซ์โหนดทุกครั้งคุณสามารถบันทึกโหนดvar converter=$("<div>");แล้วนำมาใช้ใหม่ในภายหลัง: html1=converter.text(text1).html(); html2=converter.text(text2).html();...
FrancescoMM

1

บางครั้งคุณแค่ต้องการเข้ารหัสอักขระทุกตัว ... ฟังก์ชันนี้จะแทนที่ "ทุกอย่างยกเว้นไม่มีอะไร" ใน regxp

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


1
แทนที่^ด้วยการอนุรักษ์อีโมจิ:. function encode(e){return e.replace(/[.]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
Swiss Mister

1

ชำระเงินบทช่วยสอนจาก Ourcodeworld Ourcodeworld - เข้ารหัสและถอดรหัสเอนทิตี html ด้วยจาวาสคริปต์

สิ่งสำคัญที่สุดคือตัวอย่างห้องสมุดเขา

he.encode('foo © bar ≠ baz ???? qux');
// → 'foo &#xA9; bar &#x2260; baz &#x1D306; qux'

// Passing an `options` object to `encode`, to explicitly encode all symbols:
he.encode('foo © bar ≠ baz ???? qux', {
 'encodeEverything': true
});

he.decode('foo &copy; bar &ne; baz &#x1D306; qux');
// → 'foo © bar ≠ baz ???? qux'

ไลบรารีนี้อาจทำให้การเข้ารหัสของคุณง่ายขึ้นและจัดการได้ดีขึ้น เป็นที่นิยมอัปเดตเป็นประจำและเป็นไปตามข้อกำหนด HTML ตัวมันเองไม่มีการอ้างอิงดังที่เห็นในpackage.json


OP ขอ vanilla JS และ vanilla JS มี element.innerText หากมีข้อได้เปรียบของห้องสมุดโปรดเพิ่มลงในคำตอบของคุณ
Rick

0

นี่คือวิธีที่ฉันใช้การเข้ารหัส ฉันได้รับแรงบันดาลใจจากคำตอบที่ให้ไว้ข้างต้น

function encodeHTML(str) {
  const code = {
      ' ' : '&nbsp;',
      '¢' : '&cent;',
      '£' : '&pound;',
      '¥' : '&yen;',
      '€' : '&euro;', 
      '©' : '&copy;',
      '®' : '&reg;',
      '<' : '&lt;', 
      '>' : '&gt;',  
      '"' : '&quot;', 
      '&' : '&amp;',
      '\'' : '&apos;'
  };
  return str.replace(/[\u00A0-\u9999<>\&''""]/gm, (i)=>code[i]);
}

// TEST
console.log(encodeHTML("Dolce & Gabbana"));
console.log(encodeHTML("Hamburgers < Pizza < Tacos"));
console.log(encodeHTML("Sixty > twelve"));
console.log(encodeHTML('Stuff in "quotation marks"'));
console.log(encodeHTML("Schindler's List"));
console.log(encodeHTML("<>"));


หยุดพักสำหรับอินพุตใด ๆ ใน \ u00A0- \ u9999 ที่ไม่อยู่ในรายการของคุณ
Rick

โปรดอธิบายวัตถุประสงค์ของการmปรับเปลี่ยนรูปแบบในรูปแบบที่ไม่มีจุดยึด
mickmackusa

-1

คุณสามารถใช้charCodeAt()วิธีการตรวจสอบว่าอักขระที่ระบุมีค่าสูงกว่า 127 toString(16)และแปลงเป็นตัวอักษรตัวเลขอ้างอิงใช้


4
จะดีมากถ้าคุณสามารถเพิ่มจำนวนเล็กน้อยเกี่ยวกับเลขวิเศษ127และวิธีการ / ทำไมถึงได้ผล;)
yckart

-1
replaceHtmlEntities(text) {
  var tagsToReplace = {
    '&amp;': '&',
    '&lt;': '<',
    '&gt;': '>',
  };
  var newtext = text;
  for (var tag in tagsToReplace) {
    if (Reflect.apply({}.hasOwnProperty, this, [tagsToReplace, tag])) {
      var regex = new RegExp(tag, 'g');
      newtext = newtext.replace(regex, tagsToReplace[tag]);
    }
  }
  return newtext;
}

-1

<!DOCTYPE html>
<html>
<style>
button {
backround: #ccc;
padding: 14px;
width: 400px;
font-size: 32px;
}
#demo {
font-size: 20px;
font-family: Arial;
font-weight: bold;
}
</style>
<body>

<p>Click the button to decode.</p>

<button onclick="entitycode()">Html Code</button>

<p id="demo"></p>


<script>
function entitycode() {
  var uri = "quotation  = ark __ &apos; = apostrophe  __ &amp; = ampersand __ &lt; = less-than __ &gt; = greater-than __ 	non- = reaking space __ &iexcl; = inverted exclamation mark __ &cent; = cent __ &pound; = pound __ &curren; = currency __ &yen; = yen __ &brvbar; = broken vertical bar __ &sect; = section __ &uml; = spacing diaeresis __ &copy; = copyright __ &ordf; = feminine ordinal indicator __ &laquo; = angle quotation mark (left) __ &not; = negation __ &shy; = soft hyphen __ &reg; = registered trademark __ &macr; = spacing macron __ &deg; = degree __ &plusmn; = plus-or-minus  __ &sup2; = superscript 2 __ &sup3; = superscript 3 __ &acute; = spacing acute __ &micro; = micro __ &para; = paragraph __ &middot; = middle dot __ &cedil; = spacing cedilla __ &sup1; = superscript 1 __ &ordm; = masculine ordinal indicator __ &raquo; = angle quotation mark (right) __ &frac14; = fraction 1/4 __ &frac12; = fraction 1/2 __ &frac34; = fraction 3/4 __ &iquest; = inverted question mark __ &times; = multiplication __ &divide; = division __ &Agrave; = capital a, grave accent __ &Aacute; = capital a, acute accent __ &Acirc; = capital a, circumflex accent __ &Atilde; = capital a, tilde __ &Auml; = capital a, umlaut mark __ &Aring; = capital a, ring __ &AElig; = capital ae __ &Ccedil; = capital c, cedilla __ &Egrave; = capital e, grave accent __ &Eacute; = capital e, acute accent __ &Ecirc; = capital e, circumflex accent __ &Euml; = capital e, umlaut mark __ &Igrave; = capital i, grave accent __ &Iacute; = capital i, acute accent __ &Icirc; = capital i, circumflex accent __ &Iuml; = capital i, umlaut mark __ &ETH; = capital eth, Icelandic __ &Ntilde; = capital n, tilde __ &Ograve; = capital o, grave accent __ &Oacute; = capital o, acute accent __ &Ocirc; = capital o, circumflex accent __ &Otilde; = capital o, tilde __ &Ouml; = capital o, umlaut mark __ &Oslash; = capital o, slash __ &Ugrave; = capital u, grave accent __ &Uacute; = capital u, acute accent __ &Ucirc; = capital u, circumflex accent __ &Uuml; = capital u, umlaut mark __ &Yacute; = capital y, acute accent __ &THORN; = capital THORN, Icelandic __ &szlig; = small sharp s, German __ &agrave; = small a, grave accent __ &aacute; = small a, acute accent __ &acirc; = small a, circumflex accent __ &atilde; = small a, tilde __ &auml; = small a, umlaut mark __ &aring; = small a, ring __ &aelig; = small ae __ &ccedil; = small c, cedilla __ &egrave; = small e, grave accent __ &eacute; = small e, acute accent __ &ecirc; = small e, circumflex accent __ &euml; = small e, umlaut mark __ &igrave; = small i, grave accent __ &iacute; = small i, acute accent __ &icirc; = small i, circumflex accent __ &iuml; = small i, umlaut mark __ &eth; = small eth, Icelandic __ &ntilde; = small n, tilde __ &ograve; = small o, grave accent __ &oacute; = small o, acute accent __ &ocirc; = small o, circumflex accent __ &otilde; = small o, tilde __ &ouml; = small o, umlaut mark __ &oslash; = small o, slash __ &ugrave; = small u, grave accent __ &uacute; = small u, acute accent __ &ucirc; = small u, circumflex accent __ &uuml; = small u, umlaut mark __ &yacute; = small y, acute accent __ &thorn; = small thorn, Icelandic __ &yuml; = small y, umlaut mark";
  var enc = encodeURI(uri);
  var dec = decodeURI(enc);
  var res = dec;
  document.getElementById("demo").innerHTML = res;
}
</script>

</body>
</html>


ดูเหมือนจะไม่ตอบคำถามและเป็นเพียงคำตอบสำหรับรหัสเท่านั้น โปรดระบุคำอธิบายว่าโค้ดกำลังทำอะไรและเกี่ยวข้องกับคำถามอย่างไร
Rick
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.