简体   繁体   English

Angular.js中的部分HTML字符串转义

[英]Partial HTML string escaping in Angular.js

I have read about angular's way of escaping everything by default and $sce , so I white-list data with $sce.trustAsHtml() through filter (since $sce is not working in service), like this: 我已经阅读了有关angular的默认情况下转义所有内容的方法和$sce ,所以我使用$sce.trustAsHtml()通过过滤器列出数据(因为$sce不在服务中),如下所示:

<sup class="ng-binding" ng-bind-html="row|logEntry"></sup>

But the problem is, that I don't trust some parts of HTML. 但问题是,我不相信HTML的某些部分。

To dive into details - I have translations that have HTML in it, but they have replaceable tokens/variables in them. 深入研究细节 - 我的翻译中包含HTML,但它们中包含可替换的标记/变量。 So translations support HTML , but I don't want provided tokens to include HTML. 所以翻译支持HTML ,但我不希望提供的令牌包含HTML。

My filter logEntry internally looks like this: 我的过滤器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);

For example I can have translation about userX changing article, but I don't want result text to trigger alert() if user's name includes <script>alert('evilname')</script> 例如,我可以翻译有关userX更改文章,但如果用户名包含<script>alert('evilname')</script> ,我不希望结果文本触发alert()

$translate by itself is not relevant, it can be any HTML string where I want some parts to be replaced with regular JS .replace() with content staying "as text". $translate本身是不相关的,它可以是任何HTML字符串,我希望某些部分被常规JS .replace()替换,内容保持“作为文本”。

So my question is - how can I escape parts of HTML ? 所以我的问题是 - 如何逃避HTML的部分内容 Do I have to resort to slicing it in parts inside of a view? 我是否必须在视图内部分切片? Or do I have to resort to custom escaping ( Fastest method to escape HTML tags as HTML entities? )? 或者我是否必须采用自定义转义( 最快的方法将HTML标记转义为HTML实体? )? Is there a preferred practice for such things? 这种事情是否有首选做法?

Let's start by restructuring your logEntry to separate out the interpolateParams 让我们首先重构你的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);

You want to escape all HTML from interpolateParams but leave any HTML in your translation templates. 您想要从interpolateParams转义所有HTML,但在转换模板中保留任何HTML。 Use this code to copy the object, iterate over its values and replace with escaped 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);

Lastly, the encodeEntities functionality of angular isn't exposed, so we had to borrow the source from angular-sanitize.js 最后, 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, '&amp;').
    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, '&lt;').
    replace(/>/g, '&gt;');
}

Update: After updating to angular-translate 2.7.0 this message appeared: 更新:更新为angular-translate 2.7.0后出现此消息:

pascalprecht.translate.$translateSanitization: No sanitization strategy has been configured. pascalprecht.translate。$ translateSanitization:未配置清理策略。 This can have serious security implications. 这可能会产生严重的安全隐患。 See http://angular-translate.github.io/docs/#/guide/19_security for details. 有关详细信息,请参见http://angular-translate.github.io/docs/#/guide/19_security

Sp instead of the trustlate answer above, angular-translate can accomplish the same result with: Sp而不是上面的trustlate答案,angular-translate可以完成相同的结果:

$translateProvider.useSanitizeValueStrategy('escapeParameters');

See the docs for more Sanitize Value Strategies 有关更多Sanitize Value Strategies的信息,请参阅文档

In your app add 在您的应用中添加

$translateProvider.useSanitizeValueStrategy('escapeParameters');

So that, your code looks like this : 所以,你的代码看起来像这样:

myApp.config(function ($translateProvider) {

    //...whatever

  $translateProvider.useSanitizeValueStrategy('escapeParameters');

});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM