معرفی ویژگی innerHTML در جاوا اسکریپت و نحوه استفاده از آن
در چشمانداز توسعه وب امروزی، اطمینان از اینکه صفحات وب حاوی اطلاعات مرتبط و بهروز هستند بسیار مهم است. چه نیاز به نمایش نمودار سهام، زمان فعلی، نام کاربر، یا هر داده دیگری که به صورت پویا بر اساس زمان یا تعامل کاربر تغییر میکند، مهم است که بهطور مرتب این محتوا را بهروز کنید تا بهترین تجربه را برای کاربران خود ارائه دهید. خوشبختانه یک راهحل مناسب برای ارتباط اطلاعات پویا با عناصر HTML و نمایش بیدردسر وضعیت فعلی آنها داریم و آن هم ویژگی innerHTML در جاوا اسکریپت است.
در این مطلب آموزشی از مکتوب قصد داریم که در رابطه با innerHTML در جاوا اسکریپت و نحوه و زمان استفاده از آن شما را راهنمایی کنیم. علاوه بر این، خواندن این مطلب به شما کمک میکند تا نحوه استفاده ایمن از innerHTML را درک کنید و خطر حملات بالقوه Cross-Site Scripting (XSS) را به حداقل برسانید.
innerHTML در جاوا اسکریپت چیست؟
ویژگی innerHTML در جاوا اسکریپت برای توسعهدهندگان وب دو هدف را دنبال میکند:
- این ویژگی به شما امکان میدهد محتوای HTML را در عنصر HTML به عنوان رشته بازیابی کنید.
- innerHTML به شما امکان میدهد محتوای عنصر را با HTML جدید تغییر دهید یا جایگزین کنید.
مثال HTML زیر را در نظر بگیرید:
<div id="someDivElement">
<span>Hello World</span>
</div>
برای دسترسی به innerHTML یک عنصر، ابتدا باید عنصر را با استفاده از getElementById() بازیابی کرد:
const someDivElement = document.getElementById("someDivElement");
سپس میتوانید به ویژگی innerHTML دسترسی پیدا کنید:
console.log(someDivElement.innerHTML);
با این کار رشته “<span>Hello World</span>” خروجی خواهد شد. اگر میخواهید innerHTML عنصر را تغییر دهید، میتوانید این کار را به صورت زیر انجام دهید:
someDivElement.innerHTML = "<span>Something just like this...</span>";
مثال innerHTML در جاوا اسکریپت
در اینجا مثالی آورده شده است که نحوه استفاده از innerHTML در جاوا اسکریپت را در یک برنامه کاری که در آن مواردی به فهرست کارهای موجود اضافه میشود، نشان میدهد:
const todos = [
"Exercise",
"Have milk",
"Buy bread",
"Walk the dog",
"Sleep timely :)"
];
const todoListPreview = document.getElementById("tdlst-preview"); // Returns an <ol> element
todos.forEach((todo) => {
todoListPreview.innerHTML += `<li>${todo}</li>`;
});</ol>
این کد همه موارد کار را به عنوان برچسب <li> به عنصر لیست سفارشی ما اضافه میکند. مهم است که توجه داشته باشید که استثناها میتوانند با innerHTML رخ دهند، درست مانند هر کد دیگری. یکی از استثناهای رایج، SyntaxError است، که زمانی ایجاد میشود که رشته HTML ارائه شده به خوبی شکل نگیرد. مثال زیر برای بیان این هدف مهم است:
someDivElement.innerHTML = "<span>William Bradley "Brad" Pitt</span>";
در این مورد، نقلقولهای دوگانه یا همان بک تیکها (“”) در رشته HTML باعث یک خطای نحوی میشوند، زیرا «Brad» به عنوان یک شناسه ناشناخته تفسیر شده است.
پیشنهاد مطالعه: Function در جاوا اسکریپت – راهنمای جامع
چه زمانی نباید از innerHTML در جاوا اسکریپت استفاده کرد؟
مواردی وجود دارد که باید از استفاده از innerHTML اجتناب شود، به خصوص زمانی که شامل تنظیم مقادیر باشد. دلیل آن این است که innerHTML همه تگهای HTML را میپذیرد، از جمله تگ <script>، که بهطور بالقوه میتواند در را برای حملات Cross-Site Scripting (XSS) باز کند.
حملات XSS آسیبپذیریهای امنیتی وب هستند که به مهاجمان اجازه میدهند کدهای مخرب را به یک صفحه وب تزریق کنند. هنگامی که یک کاربر ناآگاه از صفحه بازدید میکند، مرورگر وب او کد تزریق شده را اجرا کرده که میتواند منجر به دسترسی غیرمجاز به اطلاعات حساس، مانند کوکیها و دادههای شخصی شود. مثال زیر را در نظر بگیرید، جایی که یک اسکریپت مخرب برای ارسال کوکیهای کاربر به سرور مهاجم تزریق میشود و آنها را قادر میسازد تا هویت کاربر را جعل کنند و اقدامات مخرب انجام دهند:
خوشبختانه، کنسرسیوم وب جهانی (W3C) استانداردی را در مورد درج نشانهگذاری پویا در HTML منتشر کرده است که مشخص میکند عناصر اسکریپت درج شده از طریق innerHTML در جاوا اسکریپت نباید اجرا شوند. این محافظت در برابر حملات سنتی تزریق اسکریپت را ارائه میدهد. با این حال، هکرها راههای جایگزینی برای انجام حملات XSS پیدا کردهاند. بیایید مثال دیگری از تگ <img> را بررسی کنیم. مثال زیر دارای یک ویژگی onerror است که کد جاوا اسکریپت را میپذیرد و اجازه اجرا دارد.
<img decoding="async" src="123" onerror="alert('Haha!')">
وقتی مرورگر این تگ را تجزیه میکند، با خطا مواجه میشود زیرا مقدار src نامعتبر است زیرا انتظار URL دارد. در نتیجه یک خطا ایجاد میشود و از آنجایی که تگ <img> یک شنونده خطا دارد، کد جاوا اسکریپت داخل ویژگی اجرا میشود.
مهم است که هنگام استفاده از innerHTML در جاوا اسکریپت محتاط باشید و از درج محتوای تولید شده توسط کاربر یا نامعتبر بدون پاکسازی مناسب خودداری کنید. در عوض، روشهای جایگزینی را برای دستکاری و ایجاد عناصر در نظر بگیرید، مانند استفاده از روشهای دستکاری DOM یا چارچوبهایی که محافظت داخلی در برابر حملات XSS ارائه میدهند.
پیشنهاد مطالعه: آموزش class در جاوا اسکریپت به زبان ساده
نحوه استفاده از innerHTML بدون ایجاد آسیبپذیری XSS
برای جلوگیری از آسیبپذیریهای XSS هنگام استفاده از innerHTML در جاوا اسکریپت، تمیز کردن ورودی کاربر، بهویژه زمانی که آن را بهصورت HTML ارائه میکنید، بسیار مهم است. هنگام ساخت ویژگیهایی مانند ویرایشگر WYSIWYG که در آن کاربران میتوانند محتوای HTML را با استفاده از innerHTML در پایگاه داده شما ذخیره کنند، باید اقدامات تمیزکاری ورودی را برای جلوگیری از گنجاندن کدهای مخرب اجرا کنید.
چندین کتابخانه منبع باز در دسترس هستند که خدمات پاکسازی HTML را ارائه میدهند. یکی از کتابخانههای توصیهشده، sanitize-html است که هم برای محیطهای مرورگر و هم برای محیطهای Node.js تمیز کردن این پاکسازی HTML را فراهم میکند. میتوانید کتابخانه sanitize-html را با استفاده از npm به صورت زیر نصب کنید:
npm install sanitize-html
استفاده از کتابخانه نسبتاً ساده است. در اینجا چند نمونه هستند:
// Using ES module import
import sanitizeHtml from 'sanitize-html';
// Using CommonJS require
const sanitizeHtml = require('sanitize-html');
sanitizeHtml('<img src="x" onerror="alert(1)//">'); // returns ""
sanitizeHtml('<svg><g>'); // returns ""
sanitizeHtml('<p>abc<iframe>def</iframe></p>'); // returns "<p>abcdef</p>"
sanitizeHtml('<table><tr><td>HELLO</td></tr>'); // returns "<table><tr><td>HELLO</td></tr></table>"
sanitizeHtml('<ul><li><a href="//google.com">click</a></li></ul>'); // returns "<ul><li><a href="%5C%22//google.com%5C%22">click</a></li></ul>"
توجه داشته باشید که این مثالها نشان میدهند که چگونه sanitize-html میتواند کدهای مخرب بالقوه را از HTML ورودی حذف یا فرار کند. بهطور پیشفرض، sanitize-html دارای مجموعهای از قوانین از پیش تعریفشده است که برچسبها و ویژگیها مجاز هستند و سایرین را حذف یا پاکسازی میکند. با این حال، میتوان آن را با توجه به شرایط خاص سفارشی کرد. تأکید بر این نکته مهم است که همیشه باید ورودیهای رشتههای HTML را در هر دو قسمت فرانتاند و بکاند آن پاکسازی کنید تا خطر حملات XSS را به میزان قابلتوجهی کاهش دهید.
پیشنهاد مطالعه: کلمه کلیدی let در جاوا اسکریپت
innerHTML در مقابل createElement
هنگام مقایسه innerHTML و createElement، درک تفاوتها و موارد استفاده از آنها مهم است که در ادامه این تفاوتها به وضوح بیان شدهاند. createElement عموماً سریعتر است زیرا مرورگر نیازی به تجزیه یک رشته HTML و ساختن درخت گره ندارد. همچنین بر خلاف innerHTML در جاوا اسکریپت شامل پیوست کردن شنوندگان رویداد نمیشود. هنگام استفاده از innerHTML، مرورگرها باید تمام گرههای DOM را در عنصر اصلاح شده مجدداً بازبینی و ایجاد کنند.
با این حال، innerHTML میتواند یک رویکرد راحتتر و انعطافپذیرتر برای راهحلهای پویا خاص، مانند مبدل Markdown به HTML با پیشنمایش همزمان باشد. در این سناریو، innerHTML یک راهحل مناسب ارائه میدهد که کد را ساده کرده و امکان توسعه آسان را فراهم میکند. تلاش برای دستیابی به عملکرد مشابه با استفاده از createElement منجر به ایجاد کدهای پیچیدهتر و محکمتر میشود. بیایید همان مثال فهرست کارهایی را که قبلاً ذکر شد، اما از createElement به جای innerHTML استفاده کنیم:
const todos = [
"Exercise",
"Have milk",
"Buy bread",
"Walk the dog",
"Sleep timely :)"
];
const todoListPreview = document.getElementById("tdlst-preview"); // Returns an <ol> element
todos.forEach((todo) => {
todoListPreview.innerHTML += `<li>${todo}</li>`;
const listItemElement = document.createElement("li");
listItemElement.textContent = todo;
todoListPreview.appendChild(listItemElement);
});</ol>
در حالی که این رویکرد برای این مشکل خاص کار میکند، مقیاسپذیر نیست. برای مثال، اگر میخواهید یک ویرایشگر متن غنی بسازید، باید منطق جداگانهای برای هر عملکرد جدید بنویسید، تا پایگاه کد پیچیدهتر و نگهداری آن دشوار باشد. در چنین مواردی، استفاده از innerHTML در جاوا اسکریپت javascript به همراه یک پاکسازی کننده ساده HTML راهحل کارآمدتر و کاربردیتری را ارائه میدهد. این به شما امکان میدهد محتوای پویا را به راحتی مدیریت کنید و با پاکسازی ورودی HTML تولید شده توسط کاربر یا نامعتبر از آسیبپذیریهای XSS جلوگیری میکند.
پیشنهاد مطالعه: آموزش متد append در جاوا اسکریپت به زبان ساده
سخن پایانی
هنگام کار با HTML و تخصیص مقادیر به ویژگی innerHTML، ملاحظات خاصی وجود دارد که باید در نظر داشت. اگر در مورد محتوا و ایمنی آن مطمئن هستید، استفاده از innerHTML در جاوا اسکریپت قابلقبول است. با این حال، اگر محتوای تولید شده توسط کاربر یا بهطور بالقوه مخرب باشد، مهم است که اقدامات احتیاطی را انجام دهید.
یک رویکرد استفاده از createElement برای ایجاد و دستکاری پویا عناصر DOM به جای اختصاص مستقیم رشتههای HTML است. این روش میتواند سریعتر باشد و از آسیبپذیریهای احتمالی XSS مرتبط با innerHTML جلوگیری کند.
گام مهم دیگر این است که ورودی کاربر قبل از ذخیره آن در یک پایگاه داده یا رندر کردن آن به صورت HTML پاکسازی شود. کتابخانههای پاکسازی منبع باز موجود هستند که میتوانند برچسبها و ویژگیهای خاصی را حذف کنند تا رشته HTML XSS مقاوم باشد. برای کاهش خطر حملات XSS، انجام پاکسازی در هر دو قسمت فرانتاند و بکاند بسیار مهم است. در فرانتاند، پاکسازی باید در زمان رندر انجام شود، زمانی که کاربر ورودی ارائه میکند، در حالی که در بکاند، باید قبل از ذخیره محتوا در پایگاه داده انجام شود. با پیروی از این شیوهها و استفاده از اقدامات پاکسازی ورودی کاربر، میتوانید از امنیت و یکپارچگی برنامه وب خود اطمینان حاصل کرده و خطرات مرتبط با آسیبپذیریهای XSS را کاهش دهید.
آموزش جاوا اسکریپت
اگر به فکر یادگیری مهارتهای جاوا اسکریپت هستید به دورههای آموزشی جامع جاوا اسکریپت مکتب خونه بپیوندید. در مکتب خونه با مدرسان خبره، پروژههای عملی و تجربیات یادگیری تعاملی وارد دنیای جاوا اسکریپت شوید. شما چه فردی مبتدی باشید و چه به دنبال ارتقای دانش موجود خود هستید، دورههای ما برای تمام سطوح مهارت ارائه میشود. فرصت شرکت درە دورههای آموزش برنامهنویسی جاوا اسکریپت مکتب خونه را برای تسلط بر جاوا اسکریپت و تبدیل شدن به یک برنامهنویسی ماهر را از دست ندهید. برای دیدن دورههای جاوا اسکریپت میتوانید از طریق صفحه آموزش جاوا اسکریپت اقدام به این کار کنید.
منبع: CoderPad