عرض HTML الخام في Blazor باستخدام MarkupString
في أحد الأيام كنت أقوم ببناء مكون يحتاج إلى تقديم بعض HTML الذي يأتي من نظام إدارة المحتوى (CMS). كانت لدي سلسلة HTML في متغير وقمت بإسقاطها في القالب مثل @myHtml. وبالطبع، أفلت Blazor من كل شيء وقدم العلامات الفعلية كنص على الصفحة. ليس ما أردت.
#المشكلة
افتراضيًا، يقوم Blazor بتشفير أي سلسلة تعرضها في قالب. لذلك إذا كان لديك:
@code {
private string content = "<strong>Hello</strong> <em>world</em>";
}
وأنت تفعل هذا:
<div>@content</div>
ستشاهد النص الحرفي <strong>Hello</strong> <em>world</em> على الصفحة بدلاً من Hello world. يقوم Blazor بهذا عن قصد لمنع هجمات XSS، وهو السلوك الافتراضي الصحيح.
الحل: MarkupString
إذا كنت تريد فعليًا تقديم HTML خام، فيمكنك لف السلسلة في MarkupString:
<div>@((MarkupString)content)</div>
وهذا كل شيء! الآن سوف يقوم Blazor بعرض HTML كعلامة فعلية. يمكنك أيضًا إسنادها إلى متغير:
@code {
private string rawHtml = "<strong>Hello</strong> <em>world</em>";
private MarkupString HtmlContent => (MarkupString)rawHtml;
}
<div>@HtmlContent</div>
#مثال من العالم الحقيقي
كنت أقوم بسحب محتوى المدونة من واجهة برمجة التطبيقات (API) وأحتاج إلى عرضه في مكون معاينة. يحتوي المحتوى على جميع أنواع HTML - العناوين، وكتل التعليمات البرمجية، والروابط، والصور. إليك ما بدا عليه الأمر تقريبًا:
@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}");
}
}
يعمل على أكمل وجه. يتم عرض HTML من واجهة برمجة التطبيقات (API) كعلامة فعلية.
كن حذرا مع المحتوى غير الموثوق به
هذا أمر مهم: MarkupString لا** يقوم بتطهير HTML. فهو يعرض كل ما تقدمه له، بما في ذلك علامات <script>. لذا، إذا كان المحتوى يأتي من مدخلات المستخدم أو من مصدر غير موثوق به، فأنت بحاجة إلى تطهيره أولاً.
لا يوجد مطهر HTML مدمج في Blazor، ولكن يمكنك استخدام مكتبة مثل 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>
يؤدي هذا إلى استبعاد العناصر الخطيرة مثل معالجات <script> وonclick والأشياء الأخرى التي لا تريد عرضها من المحتوى المقدم من المستخدم.
#متى يتم استخدامه
أستخدم MarkupString من أجل:
- محتوى CMS أو تخفيض السعر الذي تم تحويله إلى جانب خادم HTML
- إخراج محرر النص الغني
- معاينة قوالب البريد الإلكتروني
- أي HTML تم إنشاؤه مسبقًا من مصادر موثوقة
بالنسبة لأي شيء يأتي من مدخلات المستخدم، قم دائمًا بالتعقيم أولاً. أفضل آمنة من آسف.
آمل أن تكونوا قد أحببت هذا المنصب! لا تتردد في الاتصال بي على أي وسائل التواصل الاجتماعي على **@emimontesdeoca **.