web-dev-qa-db-ja.com

特別なHTMLエンティティを含む文字列をデコードする正しい方法は何ですか?

このようなサービスリクエストからJSONが返されるとします。

{
    "message": "We're unable to complete your request at this time."
}

よくわからないなぜアポストロフィがそのようにエンコードされているのか(');私が知っているのは、それをデコードしたいということだけです。

これが私の頭に浮かんだjQueryを使った一つのアプローチです:

function decodeHtml(html) {
    return $('<div>').html(html).text();
}

しかし、それは(非常に)ハッキーなようです。もっと良い方法は何ですか? 「正しい」方法はありますか?

167
Dan Tao

これは私のお気に入りのHTML文字のデコード方法です。このコードを使用する利点は、タグも保持されることです。

function decodeHtml(html) {
    var txt = document.createElement("textarea");
    txt.innerHTML = html;
    return txt.value;
}

例: http://jsfiddle.net/k65s3/

入力:

Entity:&nbsp;Bad attempt at XSS:<script>alert('new\nline?')</script><br>

出力:

Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>
335
Rob W

これを行うためにDOMを使用しないでください。(現在受け入れられている答えで提案されているように)DOMを使用してHTMLエンティティをデコードします クロスブラウザの結果の違い

HTML標準のアルゴリズムに従って文字参照をデコードする堅牢で決定論的な解決策については、 the he library を使用してください。そのREADMEから:

he(“ HTMLエンティティ”用)は、JavaScriptで書かれた堅牢なHTMLエンティティエンコーダ/デコーダです。 HTMLによるすべての標準化された名前付き文字参照 を処理します あいまいなアンパサンド およびその他のEdgeのケース ブラウザと同じように 、広範なテストスイートを持ちます。そして、 - 他の多くのJavaScriptソリューションとは対照的に - heはさまざまなUnicode記号をうまく処理します。 オンラインデモがあります。

使い方は次のとおりです。

he.decode("We&#39;re unable to complete your request at this time.");
→ "We're unable to complete your request at this time."

免責事項:私はheライブラリの作者です。

もっと詳しい情報は このStack Overflow answer を見てください。

75
Mathias Bynens

あなたがHTML/DOMを使用したくない場合は、正規表現を使用することができます。私はこれをテストしていません。しかし、次の行に沿った何か

function parseHtmlEntities(str) {
    return str.replace(/&#([0-9]{1,3});/gi, function(match, numStr) {
        var num = parseInt(numStr, 10); // read num as normal number
        return String.fromCharCode(num);
    });
}

[編集]

注:これは数値のHTMLエンティティに対してのみ機能し、&oring;などの機能には機能しません。

[編集2]

ここでテストする機能(いくつかの誤字)を修正しました。 http://jsfiddle.net/Be2Bd/1/

29
Alxandr

jQueryはあなたのためにエンコードおよびデコードします。

function htmlDecode(value) {
  return $("<textarea/>").html(value).text();
}

function htmlEncode(value) {
  return $('<textarea/>').text(value).html();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
   $("#encoded")
  .text(htmlEncode("<img src onerror='alert(0)'>"));
   $("#decoded")
  .text(htmlDecode("&lt;img src onerror='alert(0)'&gt;"));
});
</script>

<span>htmlEncode() result:</span><br/>
<div id="encoded"></div>
<br/>
<span>htmlDecode() result:</span><br/>
<div id="decoded"></div>
25
Jason Williams

&#xxxxスタイルのエンティティを扱うためのJS関数があります。
GitHubの機能

// encode(decode) html text into html entity
var decodeHtmlEntity = function(str) {
  return str.replace(/&#(\d+);/g, function(match, dec) {
    return String.fromCharCode(dec);
  });
};

var encodeHtmlEntity = function(str) {
  var buf = [];
  for (var i=str.length-1;i>=0;i--) {
    buf.unshift(['&#', str[i].charCodeAt(), ';'].join(''));
  }
  return buf.join('');
};

var entity = '&#39640;&#32423;&#31243;&#24207;&#35774;&#35745;';
var str = '高级程序设计';
console.log(decodeHtmlEntity(entity) === str);
console.log(encodeHtmlEntity(str) === entity);
// output:
// true
// true
19
hypers

_.unescapeはあなたが探しているものを行います

https://lodash.com/docs/#unescape

7
tldr

これはとても良い答えです。あなたはこのように角度でこれを使用することができます:

 moduleDefinitions.filter('sanitize', ['$sce', function($sce) {
    return function(htmlCode) {
        var txt = document.createElement("textarea");
        txt.innerHTML = htmlCode;
        return $sce.trustAsHtml(txt.value);
    }
}]);
0
kodmanyagha