جاوااسکریپت - انگولار - 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
پاپریکا - siostra, brat

  • برچسبهایی با فضاهای اضافه چون StackOverflow آنها را هم قطع میکند.

و <bt/> همانطور که باید، به تگ عادی <br> تجزیه میشود، اما <FAR/OFF> حذف میشود - من باید راهی پیدا کنم که فقط <br>ها تجزیه شوند و بقیه رشتهها در براکتها تجزیه نشوند.

پاسخ شماره ۱

من برای مهمانی دیر رسیدم. من یک پایپ 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>

پاسخ شماره ۲

خب، معلوم شد که یا خیلی پیچیده است یا غیرممکن است که با DomSanitizer انجام شود، بنابراین راهحلی که انتخاب کردیم این بود که آن را به طور متفاوت در سمت سرور تجزیه کنیم - تگهای
به صورت عادی در پاسخ JSON باز میگردند، اما هر رشته دیگری که در «< >» قرار دارد با موجودیتهای HTML جایگزین میشود و همانطور که باید کار میکند.