Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何让字符串的dom元素渲染到页面上 #84

Open
deepthan opened this issue Aug 13, 2020 · 0 comments
Open

如何让字符串的dom元素渲染到页面上 #84

deepthan opened this issue Aug 13, 2020 · 0 comments

Comments

@deepthan
Copy link
Owner

如何让字符串的dom元素渲染到页面上

让字符串的dom元素渲染到页面上而不是以字符串的形式显示出来。

假设有这样一个字符串:

domStr = "<div style='color: red'>我是一只开心的div</div>"

1. 自定义一个管道

/**
 * dom元素渲染管道
 */ 
import { Pipe, PipeTransform } from "@angular/core";
import {
  DomSanitizer,
  SafeHtml,
  SafeStyle,
  SafeScript,
  SafeUrl,
  SafeResourceUrl
} from "@angular/platform-browser";

@Pipe({
  name: "safe"
})
export class SafePipe implements PipeTransform {
  constructor(protected sanitizer: DomSanitizer) {}

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

2. 用法

直接使用管道转换

<span [outerHTML]="domStr | safe: 'html'"> </span> 

DomSanitizer 解析

  • Angular常规Web应用程序的安全原则
  • 避免直接使用dom api
  • 启用内容安全策略(CSP)并配置web服务器以返回适当的CSP HTTP头
  • 使用离线模板编译器。
  • 使用服务器端XSS保护。
  • 使用DOM过滤器。
  • 防止CSRF或XSRF攻击。

例子

export const BROWSER_SANITIZATION_PROVIDERS: Array<any> = [
  {provide: Sanitizer, useExisting: DomSanitizer},
  {provide: DomSanitizer, useClass: DomSanitizerImpl},
];

@NgModule({
  providers: [
    BROWSER_SANITIZATION_PROVIDERS
    ...
  ],
  exports: [CommonModule, ApplicationModule]
})
export class BrowserModule {}
  • DOM 过滤器:用于过滤值中不可信的部分, 源码:
export enum SecurityContext { NONE, HTML, STYLE, SCRIPT, URL, RESOURCE_URL }

export abstract class DomSanitizer implements Sanitizer {
  abstract sanitize(context: SecurityContext, value: SafeValue|string|null): string|null;
  abstract bypassSecurityTrustHtml(value: string): SafeHtml;
  abstract bypassSecurityTrustStyle(value: string): SafeStyle;
  abstract bypassSecurityTrustScript(value: string): SafeScript;
  abstract bypassSecurityTrustUrl(value: string): SafeUrl;
  abstract bypassSecurityTrustResourceUrl(value: string): SafeResourceUrl;
}
sanitize(ctx: SecurityContext, value: SafeValue|string|null): string|null {
  if (value == null) return null;
 
  switch (ctx) {
    case SecurityContext.NONE:
      return value as string;
      
    case SecurityContext.HTML:
      if (value instanceof SafeHtmlImpl) return value.changingThisBreaksApplicationSecurity;
      this.checkNotSafeValue(value, 'HTML');
      return sanitizeHtml(this._doc, String(value));
     
    case SecurityContext.STYLE:
      if (value instanceof SafeStyleImpl) return value.changingThisBreaksApplicationSecurity;
      this.checkNotSafeValue(value, 'Style');
      return sanitizeStyle(value as string);
     
    case SecurityContext.SCRIPT:
      if (value instanceof SafeScriptImpl) return value.changingThisBreaksApplicationSecurity;
      this.checkNotSafeValue(value, 'Script');
      throw new Error('unsafe value used in a script context');
     
    case SecurityContext.URL:
      if (value instanceof SafeResourceUrlImpl || value instanceof SafeUrlImpl) {
        // Allow resource URLs in URL contexts, they are strictly more trusted.
        return value.changingThisBreaksApplicationSecurity;
      }
      this.checkNotSafeValue(value, 'URL');
      return sanitizeUrl(String(value));
     
    case SecurityContext.RESOURCE_URL:
      if (value instanceof SafeResourceUrlImpl) {
        return value.changingThisBreaksApplicationSecurity;
      }
      this.checkNotSafeValue(value, 'ResourceURL');
      throw new Error(
          'unsafe value used in a resource URL context (see http://g.co/ng/security#xss)');
         
    default:
      throw new Error(`Unexpected SecurityContext ${ctx} (see http://g.co/ng/security#xss)`);
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant