En un proyecto en Angular, si tienes un editor de texto libre por algún lado y éste te permite agregar estilos, quizá te lleves un chasco cuando, tras guardar el texto en base de datos, intentes mostrarlo por pantalla.
DomSanitizer es un servicio de Angular que ayuda a prevenir ataques a las aplicaciones. Lo que hace, básicamente, es evitar que se inyecte código malicioso en el lado del cliente. ¿Y cómo lo evita? Pues no dejando que se renderice todo lo que le parezca sospechoso.
Que esto está muy bien, pero tiene el problema de que “igual” le da por pensar que los estilos del texto que tienes guardado en base de datos son código malicioso, y te los elimina.
Por defecto, Angular reconoce TODO como potencialmente peligrosos, y lo “desinfecta” – no sé cómo se dirá en español pero el término en inglés es sanitize – quitando todos los tags que se encuentra, para evitar ejecutar algún script que no deba. También muestra un warning por consola para avisar de que lo ha hecho, porque es un buen chico y ya que te deja sin estilos al menos te avisa de por qué lo ha hecho.
Si se da el caso de que una aplicación NECESITE insertar scripts – o estilos -, es posible desactivar DomSanitizer creando un pipe personalizado.
El servicio DomSanitizer YA TIENE predefinidos métodos para este caso:
- bypassSecurityTrustHtml
- bypassSecurityTrustScript
- bypassSecurityTrustStyle
- bypassSecurityTrustUrl
- bypassSecurityTrustResourceUrl.
Así que lo único que hay que hacer es definir el pipe de tal forma que se aplique el método que toque según el contenido que se vaya a renderizar
Primero hay que crear el pipe, que si se tiene Angular CLI es tan fácil como teclear
ng g pipe NOMBREPIPE
Esto creará los archivos NOMBREPIPE.pipe.ts y NOMBREPIPE.pipe.spec.ts. El segundo archivo es el de pruebas unitarias así que para el propósito de este post lo ignoraremos un poco.
En NOMBREPIPE.pipe.ts, se inyecta DomSanitizer en el constructor – recordemos que es un servicio más de Angular -, y el transform lo dejamos así:
public transform(value: any, type: string): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl {
switch (type) {
case 'html': return this.sanitizer.bypassSecurityTrustHtml(value);
case 'style': return this.sanitizer.bypassSecurityTrustStyle(value);
case 'script': return this.sanitizer.bypassSecurityTrustScript(value);
case 'url': return this.sanitizer.bypassSecurityTrustUrl(value);
case 'resourceUrl': return this.sanitizer.bypassSecurityTrustResourceUrl(value);
default: throw new Error(`Invalid safe type specified: ${type}`);
}
}
Con esto hecho, solamente hay que usar el pipe en el contenido que Angular nos está “desinfectando”, y se mostrará todo correctamente. Por ejemplo, en el caso del texto cuyos estilos queremos que no se borren al renderizar la página:
<div class="content-inner" [innerHTML]="variableQueContieneElTextoConEstilos| safe: 'html'"></div>
Y ya.
************************************************************
Espero que esta entrada pueda ser de utilidad, y si no, como siempre, aquí tenéis un gato para compensar.