Angular2 динамически вставляет тег сценария
Я получаю из содержимого сервера в поле объекта JSON, где это HTML, <style></style>
а также <script></script>
теги, и я хочу выполнить это так:
[innerHtml] = "content | sanitize", но <script></script>
теги не выполняются. Можно ли заставить его работать?
Моя дезинфицирующая труба выглядит так:
import {Pipe} from '@angular/core';
import {DomSanitizationService} from '@angular/platform-browser';
@Pipe({
name: 'sanitize',
pure: true
})
export class Sanitize {
constructor(private sanitizer: DomSanitizationService) {
}
transform(html: string) {
return this.sanitizer.bypassSecurityTrustHtml(html);
}
}
Я знаю, что в DomSanitizationService есть функция bypassSecurityTrustScript, но как ее использовать в моем случае?
3 ответа
Решение
Это не проблема угловых 2, script
теги, вставленные через innerHTML, не выполняются.
Если у вас есть строка HTML, которая содержит script
теги вставьте так:
const fragment = document.createRange().createContextualFragment(yourHtmlString);
anyElement.appendChild(fragment);
Это решит проблему...
import { Pipe } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({
name: 'sanitize',
pure: true
})
export class Sanitize {
constructor(private domSanitizer: DomSanitizer) { }
handleExternalScriptsInHtmlString(string) {
let that = this;
var parser = new DOMParser();
var scripts = parser.parseFromString(string, 'text/html').getElementsByTagName('script');
var results = [];
for (var i = 0; i < scripts.length; i++) {
var src = scripts[i].getAttribute('src');
if (src.length && results.indexOf(src) === -1) {
results.push(src);
that.addScript(src);
}
}
return results;
}
addScript(src) {
var script = document.createElement('script');
script.setAttribute('src', src);
document.body.appendChild(script);
}
transform(htmlContent: any) {
let sanitizeHtmlContent = this.domSanitizer.bypassSecurityTrustHtml(htmlContent);
this.handleExternalScriptsInHtmlString(htmlContent);
return sanitizeHtmlContent;
}
}
Там нет углового пути... Вы должны сделать это так....
import { Pipe } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({
name: 'sanitize',
pure: true
})
export class Sanitize {
constructor(private domSanitizer: DomSanitizer) { }
handleExternalScriptsInHtmlString(string) {
let that = this;
var parser = new DOMParser();
var scripts = parser.parseFromString(string, 'text/html').getElementsByTagName('script');
var results = [];
for (var i = 0; i < scripts.length; i++) {
var src = scripts[i].getAttribute('src');
if (src.length && results.indexOf(src) === -1) {
results.push(src);
that.addScript(src);
}
}
return results;
}
addScript(src) {
var script = document.createElement('script');
script.setAttribute('src', src);
document.body.appendChild(script);
}
transform(htmlContent: any) {
let sanitizeHtmlContent = this.domSanitizer.bypassSecurityTrustHtml(htmlContent);
this.handleExternalScriptsInHtmlString(htmlContent);
return sanitizeHtmlContent;
}
}