Rendern von Roh-HTML in Blazor mit MarkupString

· 2 Min. Lesezeit

Neulich habe ich eine Komponente erstellt, die HTML rendern musste, das von einem CMS kam. Ich hatte die HTML-Zeichenfolge in einer Variablen und habe sie einfach wie @myHtml in die Vorlage eingefügt. Und natürlich hat Blazor alles umgangen und die eigentlichen Tags als Text auf der Seite dargestellt. Nicht das, was ich wollte.

Das Problem

Standardmäßig codiert Blazor jede Zeichenfolge, die Sie in einer Vorlage rendern. Wenn Sie also Folgendes haben:

@code {
    private string content = "<strong>Hello</strong> <em>world</em>";
}

Und du machst das:

<div>@content</div>

Auf der Seite wird anstelle von Hallo Welt der wörtliche Text <strong>Hello</strong> <em>world</em> angezeigt. Blazor tut dies absichtlich, um XSS-Angriffe zu verhindern, was das richtige Standardverhalten ist.

Die Lösung: MarkupString

Wenn Sie tatsächlich rohes HTML rendern müssen, packen Sie Ihre Zeichenfolge in ein MarkupString:

<div>@((MarkupString)content)</div>

Und das ist es! Jetzt rendert Blazor den HTML-Code als tatsächliches Markup. Sie können es auch einer Variablen zuweisen:

@code {
    private string rawHtml = "<strong>Hello</strong> <em>world</em>";
    private MarkupString HtmlContent => (MarkupString)rawHtml;
}
<div>@HtmlContent</div>

Ein Beispiel aus der Praxis

Ich habe Blog-Inhalte von einer API abgerufen und musste sie in einer Vorschaukomponente rendern. Der Inhalt enthielt alle Arten von HTML – Überschriften, Codeblöcke, Links, Bilder. So ungefähr sah es aus:

@inject HttpClient Http

@if (article is not null)
{
    <article>
        <h1>@article.Title</h1>
        <div class="content">
            @((MarkupString)article.HtmlBody)
        </div>
    </article>
}

@code {
    [Parameter]
    public int ArticleId { get; set; }

    private ArticleDto? article;

    protected override async Task OnInitializedAsync()
    {
        article = await Http.GetFromJsonAsync<ArticleDto>($"api/articles/{ArticleId}");
    }
}

Funktioniert perfekt. Der HTML-Code der API wird als eigentliches Markup gerendert.

Seien Sie vorsichtig mit nicht vertrauenswürdigen Inhalten

Das ist wichtig: MarkupString bereinigt den HTML-Code nicht. Es rendert alles, was Sie ihm geben, einschließlich <script>-Tags. Wenn der Inhalt also aus Benutzereingaben oder einer nicht vertrauenswürdigen Quelle stammt, müssen Sie ihn zuerst bereinigen.

In Blazor gibt es keinen integrierten HTML-Sanitizer, aber Sie können eine Bibliothek wie [HtmlSanitizer](https://github.com/mganss/HtmlSanitizer verwenden):

using Ganss.Xss;

@code {
    private HtmlSanitizer sanitizer = new();

    private MarkupString SafeHtml(string html)
    {
        var clean = sanitizer.Sanitize(html);
        return (MarkupString)clean;
    }
}
<div>@SafeHtml(untrustedContent)</div>

Dadurch werden gefährliche Elemente wie <script>, onclick-Handler und andere Dinge entfernt, die nicht aus vom Benutzer bereitgestellten Inhalten gerendert werden sollen.

Wann man es verwenden sollte

Ich verwende MarkupString für:

– CMS-Inhalt oder Markdown, der serverseitig in HTML konvertiert wurde

  • Rich-Text-Editor-Ausgabe
  • Vorschau der E-Mail-Vorlagen
  • Alle vorgefertigten HTML-Codes aus vertrauenswürdigen Quellen

Alles, was aus Benutzereingaben stammt, muss immer zuerst bereinigt werden. Vorsicht ist besser als Nachsicht.

Ich hoffe, Ihnen hat der Beitrag gefallen! Sie können mich gerne in den sozialen Medien unter @emimontesdeoca kontaktieren.

Ressourcen