目次
HTMLエスケープの注意点
昨日、このような記事がはてブに上がっていた。
innerText(textContent)/innerHTMLを使ったHTMLエスケープは充分でないので今すぐやめろ、お前たちはもう終わりだ
要約するとreturn $('<div />').text(content).html()を使用したやり方だと「"」などをエスケープしないので.replaceで置き換えたものを使いましょうという話。
ただし、元記事のコードだと`(グレイヴアクセント)の置換処理が入っていなかったので下記のように書き換えるほうが良さそうだ。
var str = '& < > ` " ' + "'"; var escapeHtml = (function (String) { var escapeMap = { '&': '&', "'": ''', '`': '`', '"': '"', '<': '<', '>': '>' }; var escapeReg = '['; var reg; for (var p in escapeMap) { if (escapeMap.hasOwnProperty(p)) { escapeReg += p; } } escapeReg += ']'; reg = new RegExp(escapeReg, 'g'); return function escapeHtml (str) { str = (str === null || str === undefined) ? '' : '' + str; return str.replace(reg, function (match) { return escapeMap[match]; }); }; }(String)); console.log(escapeHtml(str)); // => & < > ` " '
ライブラリを使用している場合
jQueryはHTMLエスケープのメソッドが存在しないがJavaScriptライブラリによってはエスケープのメソッドがあらかじめ用意されている場合がある。
Underscore.jsのHTMLエスケープ
※Underscore.js 1.6.0以下は`(グレイヴアクセント)を置換しないので注意
var str = '& < > " ` ' + "'"; str = _.escape(str); console.log(str); // => & < > " ` 
prototype.jsのHTMLエスケープ
escapeHTML()があるが& < >しかエスケープしないので使用しないほうが良い。
var str = '& < > " ` ' + "'"; console.log(str.escapeHTML()); // => & < > " ` '
HTMLエスケープ用メソッドがないライブラリ
- jQuery
- AngularJS
- Vue.jsなど
※AngularJSやVue.jsはバインディングの際にHTMLエスケープしてくれるので通常はHTMLエスケープ用メソッドは必要がない。
追記:ES6によるモダンなコードを追加
const htmlEscape = (str) => { if (!str) return; return str.replace(/[<>&"'`]/g, (match) => { const escape = { '<': '<', '>': '>', '&': '&', '"': '"', "'": ''', '`': '`' }; return escape[match]; }); } console.log(htmlEscape('& < > ` " ' + "'")); // => & < > ` " '