我已经阅读了 Angular 转义默认情况下的所有内容 和 $sce
的方法。 ,所以我用 $sce.trustAsHtml()
将数据列入白名单通过过滤器(因为 $sce
在服务中不起作用),像这样:
<sup class="ng-binding" ng-bind-html="row|logEntry"></sup>
但问题是,我不信任 HTML 的某些部分。
要深入了解细节 - 我有 translations其中包含 HTML,但其中包含可替换的标记/变量。所以translations support HTML ,但我不希望提供的标记包含 HTML。
我的过滤器 logEntry
内部看起来像这样:
var translated = $translate('Log.' + msg.context.entity_type) + '.' + msg.context.action, {
'object_name': msg.context.object_name,
'user': msg.context.user_name
});
return $sce.trustAsHtml(translated);
例如,我可以翻译有关 userX 更改文章的内容,但如果用户名包含 <script>alert('evilname')</script>
,我不希望结果文本触发 alert()
$translate
本身是不相关的,它可以是任何我希望用常规 JS 替换某些部分的 HTML 字符串 .replace()
内容保持“文本”状态。
所以我的问题是 - 如何转义部分 HTML?我是否必须求助于在 View 内将其分成几部分?还是我必须求助于自定义转义( Fastest method to escape HTML tags as HTML entities? )?是否有针对此类事情的首选做法?
最佳答案
让我们开始重组您的 logEntry
以分离出 interpolateParams
var translationId = 'Log.' + msg.context.entity_type) + '.' + msg.context.action;
var interpolateParams = {
'object_name': msg.context.object_name,
'user': msg.context.user_name
};
var translated = $translate(translationId, interpolateParams);
return $sce.trustAsHtml(translated);
您想从 interpolateParams
中转义所有 HTML,但将所有 HTML 保留在您的翻译模板中。使用此代码复制对象,迭代其值并替换为转义的 HTML。
var safeParams = angular.copy(interpolateParams);
angular.forEach(safeParams, function(value, key, obj) {
obj[key] = encodeEntities(value)
// if you want safe/sanitized HTML, use this instead
// obj[key] = $sanitize(value);
});
var translated = $translate(translationId, safeParams);
最后,angular 的encodeEntities
功能没有公开,所以我们不得不从angular-sanitize.js 借用源代码。
var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
// Match everything outside of normal chars and " (quote character)
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
function encodeEntities(value) {
return value.
replace(/&/g, '&').
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, '<').
replace(/>/g, '>');
}
更新:更新到 angular-translate 2.7.0 后出现此消息:
pascalprecht.translate.$translateSanitization: No sanitization strategy has been configured. This can have serious security implications. See http://angular-translate.github.io/docs/#/guide/19_security for details.
Sp 而不是上面的 truSTLate
答案,angular-translate 可以通过以下方式实现相同的结果:
$translateProvider.useSanitizeValueStrategy('escapeParameters');
查看文档了解更多清理值(value)策略
关于javascript - Angular.js 中的部分 HTML 字符串转义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27061305/