2014-11-21 2 views
5

ich über Winkel Weg lesen alles zu entkommen standardmäßig und $sce, so dass ich weiß-Listendaten mit $sce.trustAsHtml() durch Filter (seit $sce funktioniert nicht in Betrieb ist), wie folgt aus:Teil HTML-String in Angularjs Flucht

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

Aber das Problem ist, dass ich einige Teile von HTML nicht traue.

Um in Details zu tauchen - ich habe translations, die HTML enthalten, aber sie haben ersetzbare Token/Variablen in ihnen. Also translations support HTML, aber ich möchte nicht, dass Token HTML enthalten.

Mein Filter logEntry sieht intern wie folgt aus:

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); 

Zum Beispiel I Übersetzung haben kann über UserX Artikel zu ändern, aber ich will nicht Ergebnis Text Alarm auslösen(), wenn der Benutzer den Namen <script>alert('evilname')</script> enthält

$translate an sich ist nicht relevant, es kann jeder HTML-String sein, wo ich einige Teile mit regulären JS .replace() mit Inhalt bleiben "als Text" ersetzt werden soll.

Also meine Frage ist - Wie kann ich Teile von HTML entkommen? Muss ich darauf zurückgreifen, Teile in einer Ansicht zu schneiden? Oder muss ich auf benutzerdefinierte Entweichen zurückgreifen ( Fastest method to escape HTML tags as HTML entities?)? Gibt es eine bevorzugte Praxis für solche Dinge?

Antwort

5

Beginnen wir mit Ihrer logEntry Umstrukturierung der 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); 

Sie möchten trennen Sie alle HTML-von interpolateParams zu entkommen, aber jede HTML-Code in Ihre Übersetzung Vorlagen lassen. Verwenden Sie diesen Code, um das Objekt zu kopieren, über seine Werte zu iterieren und durch maskiertes HTML zu ersetzen.

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); 

schließlich die encodeEntities Funktionalität von Winkel nicht ausgesetzt ist, so mussten wir die Quelle von 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;'); 
} 

aktualisieren borgen: Nach der Aktualisierung auf Winkel übersetzen 2.7.0 Diese Nachricht erschienen.

pascalprecht.translate $ translateSanitization: Nein sanitization Strategie war Konfi gured. Dies kann ernste Sicherheit haben Auswirkungen. Siehe http://angular-translate.github.io/docs/#/guide/19_security für Details.

Sp anstelle der trustlate Antwort oben, Winkel übersetzen kann mit dem gleichen Ergebnis erreichen:

$translateProvider.useSanitizeValueStrategy('escapeParameters'); 

die Dokumentation finden Sie weitere Sanitize Value-Strategien

2

In Ihrer App

hinzufügen
$translateProvider.useSanitizeValueStrategy('escapeParameters'); 

So sieht Ihr Code aus dieses:

myApp.config(function ($translateProvider) { 

    //...whatever 

    $translateProvider.useSanitizeValueStrategy('escapeParameters'); 

});