与えられたテキスト
_<b>This is some text</b>
_
これを自分のページに書き込んで、次のように表示したいと思います。
_<b>This is some text</b>
_
これは好きじゃない
これはテキストです
escape("<b>This is some text</b>")
を使用すると、Firefoxでこの素敵な宝石が得られます
_%3Cb%3EThis%20is%20some%20text%3C/b%3E
_
私が求めているものを免れません。何か案は?
これはあなたのために働くはずです: http://blog.nickburwell.com/2011/02/escape-html-tags-in-javascript.html
function escapeHTML( string )
{
var pre = document.createElement('pre');
var text = document.createTextNode( string );
pre.appendChild(text);
return pre.innerHTML;
}
セキュリティ警告
関数は一重引用符と二重引用符をエスケープしません。誤ったコンテキストで使用すると、XSSが発生する可能性があります。例えば:
var userWebsite = '" onmouseover="alert(\'gotcha\')" "';
var profileLink = '<a href="' + escapeHtml(userWebsite) + '">Bob</a>';
var div = document.getElemenetById('target');
div.innerHtml = profileLink;
// <a href="" onmouseover="alert('gotcha')" "">Bob</a>
私はこれをやった:
function escapeHTML(s) {
return s.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
}
HTML DOMドキュメントが利用できる状況では@limcの回答が好きです。
Node.jsなどの非HTML DOMドキュメント環境に対する@Michele Bosiと@Paoloの回答が好きです。
@Michael Bosiの答えは、replaceを4回呼び出す必要をなくすことで最適化できます。
function escape(s) {
let lookup = {
'&': "&",
'"': """,
'<': "<",
'>': ">"
};
return s.replace( /[&"<>]/g, (c) => lookup[c] );
}
console.log(escape("<b>This is some text.</b>"));
@Paoloの範囲テストは、適切に選択された正規表現を使用して最適化でき、forループは、置換関数を使用して削除できます。
function escape(s) {
return s.replace(
/[^0-9A-Za-z ]/g,
c => "&#" + c.charCodeAt(0) + ";"
);
}
console.log(escape("<b>This is some text</b>"));
@Paoloが示したように、この戦略はより多くのシナリオで機能します。
XHTMLを使用している場合は、CDATA
セクションを使用する必要があります。これらはHTMLでも使用できますが、HTMLはそれほど厳密ではありません。
文字列定数を分割して、このコードがCDATAブロック内のXHTMLでインラインで機能するようにしました。 JavaScriptを個別のファイルとして調達する場合は、それを気にする必要はありません。 areインラインJavaScriptでXHTMLを使用する場合、needを使用してコードをCDATAブロックで囲む必要があります。そうしないと機能しません。奇妙な微妙なエラーに遭遇します。
function htmlentities(text) {
var escaped = text.replace(/\]\]>/g, ']]' + '>]]><' + '![CDATA[');
return '<' + '![CDATA[' + escaped + ']]' + '>';
}
テキストをエスケープする「適切な」方法は、DOM関数document.createTextNode
を使用することです。これは実際にはテキストをエスケープしません。本質的に解析されないテキスト要素を作成するようブラウザに指示するだけです。ただし、このメソッドを機能させるにはDOMを使用する必要があります。つまり、appendChild
プロパティなどとは対照的に、innerHTML
などのメソッドを使用する必要があります。これにより、ID an-element
の要素に(X)HTMLとして解析されないテキストが入力されます。
var textNode = document.createTextNode("<strong>This won't be bold. The tags " +
"will be visible.</strong>");
document.getElementById('an-element').appendChild(textNode);
jQueryはcreateTextNode
という名前のtext
という便利なラッパーを提供します。とても便利です。 jQueryを使用した同じ機能は次のとおりです。
$('#an-element').text("<strong>This won't be bold. The tags will be " +
"visible.</strong>");
山かっこをHTMLエンティティに置き換える関数を次に示します。他の文字も含めるように拡張することもできます。
function htmlEntities( html ) {
html = html.replace( /[<>]/g, function( match ) {
if( match === '<' ) return '<';
else return '>';
});
return html;
}
console.log( htmlEntities( '<b>replaced</b>' ) ); // <b>replaced</b>
文字列内のすべての文字をエンコードできます。
function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
または、次のように、心配するメインキャラクター(&、inebreak、<、>、 "、 ')をターゲットにします。
function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}
test.value=encode('Encode HTML entities!\n\n"Safe" escape <script id=\'\'> & useful in <pre> tags!');
testing.innerHTML=test.value;
/*************
* \x26 is &ersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55"></textarea>
<div id="testing">www.WHAK.com</div>
これを試してください JavaScriptのHTMLエンティティ
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
}
&#nnn;az AZ 0-を除く)表記ですべての文字をエスケープする次の関数を使用します9およびスペース
_function Escape( s )
{
var h,
i,
n,
c;
n = s.length;
h = '';
for( i = 0; i < n; i++ )
{
c = s.charCodeAt( i );
if( ( c >= 48 && c <= 57 )
||( c >= 65 && c <= 90 )
||( c >= 97 && c <=122 )
||( c == 32 ) )
{
h += String.fromCharCode( c );
}
else
{
h += '&#' + c + ';';
}
}
return h;
}
_
例:
Escape('<b>This is some text</b>')
戻り値
_<b>This is some text</b>
_
関数は、コードインジェクション攻撃の証拠、Unicodeの証拠、純粋なJavaScriptです。
このアプローチは、DOMテキストノードを作成するアプローチよりも約50倍遅いですが、関数は100〜150ミリ秒で100万(1,000,000)文字の文字列をエスケープします。
(2011年初頭のMacBook Pro-Safari 9-Mavericksでテスト済み)