مقدمه
یکی از ستونهای اصلی امنیت در وب، «سیاست مبدأ یکسان» یا Same-Origin Policy است. این سیاست
به طور کلی اجازه نمیدهد که یک اسکریپت از یک مبدأ (ترکیبی از پروتکل، دامنه و پورت) به محتوای یک
صفحه از مبدأ دیگر دسترسی پیدا کند. این یک ویژگی امنیتی حیاتی است، اما گاهی اوقات ما نیاز داریم
که بین دو زمینه (context) مختلف، مانند یک صفحه اصلی و یک <iframe> که از دامنهی دیگری
بارگذاری شده، ارتباط برقرار کنیم.
Cross-Context Messaging یا «پیامرسانی بین زمینهای»، یک مکانیزم استاندارد و امن برای حل
این مشکل فراهم میکند. این API به ما اجازه میدهد تا بین پنجرههای مختلف (شامل تبها، پاپآپها
و `iframe`ها) و حتی `Worker`ها، صرف نظر از مبدأ آنها، پیام ارسال و دریافت کنیم.
ارسال پیام با postMessage
قلب این API، متد postMessage() است. این متد روی شیء window
زمینه هدف (مثلاً پنجره پاپآپ یا contentWindow یک <iframe>) فراخوانی میشود و دو
آرگومان اصلی میگیرد: postMessage(message, targetOrigin).
- message: دادهای که میخواهید ارسال کنید. این داده میتواند تقریباً هر نوع دادهی
قابل شبیهسازی (مانند رشته، عدد، آرایه، یا شیء ساده) باشد.
- targetOrigin: این آرگومان امنیتی بسیار مهمی است. شما مشخص میکنید که پیام فقط در
صورتی باید ارسال شود که مبدأ پنجره هدف با این مقدار برابر باشد. برای امنیت بیشتر، همیشه باید
مبدأ دقیق (مثلاً 'https://example.com') را مشخص کنید. استفاده از '*' به معنی
ارسال به هر مبدآ است و تنها زمانی باید استفاده شود که دادهی ارسالی حساس نباشد.
JAVASCRIPT
const iframe = document.getElementById('my-iframe');
iframe.addEventListener('load', () => {
const message = { userId: 42, action: 'login' };
iframe.contentWindow.postMessage(message, 'https://iframe-origin.com');
});
در کد بالا، صفحه اصلی منتظر بارگذاری کامل <iframe> میماند. سپس یک شیء پیام ساخته و آن را
با استفاده از postMessage() به پنجرهی <iframe> ارسال میکند،
اما تنها به این شرط که مبدأ فعلی <iframe> دقیقاً 'https://iframe-origin.com' باشد.
دریافت پیامها
برای دریافت پیامها، پنجره مقصد باید یک شنونده برای رویداد message روی شیء window
خود ثبت کند.
تابع شنونده، یک شیء event دریافت میکند که حاوی اطلاعات مهمی است:
- event.data: حاوی دادهی واقعی است که ارسال شده.
- event.origin: مبدأ پنجرهای که پیام را ارسال کرده است. بررسی امنیتی این
پراپرتی قبل از پردازش دادهها ضروری است.
- event.source: ارجاعی به شیء window فرستنده، که میتوان از آن برای ارسال پیام
پاسخ استفاده کرد.
JAVASCRIPT
window.addEventListener('message', (event) => {
if (event.origin !== 'https://parent-origin.com') {
console.warn('Message from untrusted origin ignored:', event.origin);
return;
}
const receivedData = event.data;
console.log('Message from parent received:', receivedData);
event.source.postMessage('Message received successfully!', event.origin);
});
در این کد، اسکریپت داخل <iframe> به رویداد message گوش میدهد. اولین و مهمترین
قدم، بررسی event.origin برای اطمینان از این است که پیام از یک منبع مورد اعتماد (صفحه
والد) آمده است. در صورت تأیید، دادهها پردازش شده و یک پیام پاسخ به فرستنده اصلی ارسال میشود.
در این درس یاد گرفتیم که چگونه با استفاده از postMessage()، سد
سیاست مبدأ یکسان» را به صورت ایمن دور بزنیم و بین زمینههای مختلف مرورگر ارتباط برقرار کنیم.
کلید امنیت در این فرآیند، مشخص کردن دقیق مبدأ هدف توسط فرستنده و بررسی دقیق مبدأ فرستنده توسط
گیرنده است. در درس بعدی، با Encoding API آشنا خواهیم شد که ابزارهایی برای کار با انکودینگهای
مختلف کاراکتر و تبدیل رشتهها به دادههای باینری فراهم میکند.