網站搜尋

javascript - Angular - innerHTML,轉義小於/大於字符,但保持 <br /> 不變


所以我有一個 Angular 8 應用程式,其中有一個表格正在顯示解析後的 XML 內容,但有些情況下,字串中可能包含需要作為 HTML 解析的
標籤,同時還有其他用小於或大於符號括起來的內容,例如。我正在使用 [innerHTML] 將其注入到一個 標籤中,但這些括起來的字串會被截斷。我嘗試過像這樣使用 DomSanitizer:

public sanitizeDsxText(text: any): any {
    return this.sanitizer.bypassSecurityTrustHtml(text);
}

但不幸的是,那也沒有作用。有沒有人曾經遇到過類似的問題並能提供一個簡單的解決方案?我將非常感激 :),

編輯:應要求,更精確地說。我有一個像這樣的:

<td class="dsx-table__cell" [innerHTML]="item.target?.txt">
</td>

「item.target?.txt」中的文字如下所示:「Cześć wam, tu bliźniaki dwa
Paprika - siostra, brat 」 *

  • 標籤中添加了空格,因為 StackOverflow 也會截斷它們。

而且 <bt/> 會像應該的那樣被解析成普通的 <br> 標籤,但 <FAR/OFF> 會被刪掉——我需要找到一種方法,只解析 <br> 標籤,而保留其他括號內的字串不被解析。

答案#1

我來晚了。我創建了一個 Angular 管道,它可以讓你有選擇地允許標籤,或者選擇將它們轉換為 HTML 實體。

這是代碼:

import { Pipe, PipeTransform } from "@angular/core";
import { DomSanitizer } from "@angular/platform-browser";
import DOMPurify from "dompurify";

@Pipe({
  name: "safeHtml",
})
export class SafeHtmlPipe implements PipeTransform {
  constructor(private domSanitizer: DomSanitizer) {
    // How to securely allow target attribute
    // https://github.com/cure53/DOMPurify/issues/317
    DOMPurify.addHook("afterSanitizeAttributes", function (node: Element) {
      // set all elements owning target to target=_blank
      if ("target" in node) {
        (node as Element).setAttribute("target", "_blank");
        (node as Element).setAttribute("rel", "noopener");
      }
    });
  }

  transform(html: string, convertToEntity: boolean, additionalTags?: string[]): string {
    if (html.length > 0) {
      // we don't want tags such as `<input>` or any form elements
      // from being displayed, and at the same time allows certain
      // tags element for styling
      const sanitizeOptions = {
        FORBID_TAGS: ["script", "form", "input", "select", "textarea"],
        ADD_TAGS: ["b", "i", "em", "span"],
        ALLOW_UNKNOWN_PROTOCOLS: true,
        // NOTE: we enable this one if in case the addHook method has unexpected behavior
        // ADD_ATTR: ["target"],
      };

      if (additionalTags && additionalTags.length) {
        sanitizeOptions.ADD_TAGS.push(...additionalTags);
      }

      let sanitizedContent = html;

      if (convertToEntity) {
        sanitizedContent = this.escapeHtml(html);
      } else {
        sanitizedContent = DOMPurify.sanitize(html, sanitizeOptions);
      }

      return this.domSanitizer.bypassSecurityTrustHtml(sanitizedContent) as string;
    }

    return html;
  }

  private escapeHtml(str: string): string {
    // DOMSanitizer or DOMPurify doesn't have options to convert special characters
    // to html entities
    return str
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
  }
}

用法:

  • 允許 img 和 a 標籤
<div class="modal-body" [innerHTML]="message | safeHtml: false:['img', 'a']"></div>
  • 透過將特殊字元轉換為其相應的 HTML 實體來轉義字串。這對於在不擔心 XSS 的情況下以字串形式顯示程式碼非常有用
<p [innerHTML]="content | safeHtml: true"></p>

答案#2

結果發現用 DomSanitizer 要麼太複雜,要麼無法實現,所以我們選擇的解決方案是在後端以不同的方式解析 ——
標籤在 JSON 回應中正常返回,但其他用 "< >" 括起的字符串都被替換為 HTML 實體,並且運作如同應該的那樣。