Rendu du HTML brut dans Blazor avec MarkupString
L’autre jour, je construisais un composant qui devait restituer du HTML provenant d’un CMS. J’avais la chaîne HTML dans une variable et je l’ai simplement déposée dans le modèle comme @myHtml. Et bien sûr, Blazor a échappé à tout et a rendu les balises réelles sous forme de texte sur la page. Pas ce que je voulais.
Le problème
Par défaut, Blazor encode toute chaîne que vous restituez dans un modèle. Alors si vous avez :
@code {
private string content = "<strong>Hello</strong> <em>world</em>";
}
Et tu fais ceci :
<div>@content</div>
Vous verrez le texte littéral <strong>Hello</strong> <em>world</em> sur la page au lieu de Hello world. Blazor le fait exprès pour empêcher les attaques XSS, ce qui est le bon comportement par défaut.
La solution : MarkupString
Si vous avez réellement besoin de restituer du HTML brut, vous enveloppez votre chaîne dans un MarkupString :
<div>@((MarkupString)content)</div>
Et c’est tout ! Maintenant, Blazor rendra le HTML sous forme de balisage réel. Vous pouvez également l’affecter à une variable :
@code {
private string rawHtml = "<strong>Hello</strong> <em>world</em>";
private MarkupString HtmlContent => (MarkupString)rawHtml;
}
<div>@HtmlContent</div>
Un exemple concret
J’extraisais le contenu du blog à partir d’une API et je devais le restituer dans un composant de prévisualisation. Le contenu contenait toutes sortes de HTML : titres, blocs de code, liens, images. Voici à peu près à quoi cela ressemblait :
@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}");
}
}
Fonctionne parfaitement. Le code HTML de l’API est rendu sous forme de balisage réel.
Soyez prudent avec le contenu non fiable
C’est important : MarkupString ne nettoie pas le code HTML. Il restitue tout ce que vous lui donnez, y compris les balises <script>. Ainsi, si le contenu provient d’une entrée d’utilisateur ou d’une source non fiable, vous devez d’abord le nettoyer.
Il n’y a pas de désinfectant HTML intégré dans Blazor, mais vous pouvez utiliser une bibliothèque comme HtmlSanitizer :
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>
Cela supprime les éléments dangereux tels que les gestionnaires <script>, onclick et d’autres éléments que vous ne souhaitez pas rendre à partir du contenu fourni par l’utilisateur.
Quand l’utiliser
J’utilise MarkupString pour :
- Contenu CMS ou démarque converti en HTML côté serveur
- Sortie de l’éditeur de texte enrichi
- Aperçu des modèles d’e-mails
- Tout code HTML prédéfini provenant de sources fiables
Pour tout ce qui provient de la saisie de l’utilisateur, nettoyez toujours en premier. Mieux vaut prévenir que guérir.
J’espère que vous avez aimé le message ! N’hésitez pas à me contacter sur tous les réseaux sociaux à @emimontesdeoca.