
در وب، یکی از مهمترین چالشها همیشه ارتباط بین دامنههای مختلف بوده. مرورگرها برای حفظ امنیت کاربر، قانونی به نام Same-Origin Policy دارند که اجازه نمیدهد یک سایت بهصورت مستقیم به منابع سایتهای دیگر درخواست بفرستد.
در گذشته، زمانی که هنوز مفهومی به نام CORS وجود نداشت، این محدودیت تبدیل به یک مشکل جدی برای برنامهنویسها شد. نیاز به دریافت داده از دامنههای دیگر وجود داشت، اما مرورگر اجازه نمیداد. دقیقاً در همین نقطه بود که راهحلی خلاقانه به نام JSONP بهوجود آمد.
Same-Origin Policy یک قانون امنیتی در مرورگر است که میگوید:
اسکریپتهای اجراشده در یک دامنه، فقط اجازه دسترسی به منابع همان دامنه را دارند.
منظور از «Origin» ترکیب این سه مورد است:
پروتکل (http / https)
دامنه
پورت
اگر یکی از اینها متفاوت باشد، مرورگر درخواست AJAX را بلاک میکند.
نکته مهم اینجاست که این محدودیت برای درخواستهای AJAX اعمال میشود، نه برای تمام منابع.
برنامهنویسها متوجه یک نکتهی جالب شدند:
تگ شامل محدودیت Same-Origin Policy نمیشود.
یعنی مرورگر بدون هیچ اعتراضی میتواند یک فایل جاوااسکریپت را از هر دامنهای دانلود و اجرا کند. همین تفاوت، پایهی اصلی JSONP شد.
ایده این بود:
بهجای گرفتن «داده»
کاری کنیم سرور «کد جاوااسکریپت» برگرداند
و مرورگر آن کد را اجرا کند
روشی قدیمی برای دریافت داده از دامنهای دیگر است که از قابلیت اجرای تگ سوءاستفاده (یا بهتر بگوییم استفادهی خلاقانه) میکند.
در JSONP:
داده بهصورت JSON است
اما داخل یک تابع جاوااسکریپت پیچیده میشود
به این پیچیدن داده داخل تابع، Padding گفته میشود.
در حالت عادی، پاسخ سرور به این شکل است:
{ "name": "Ali", "age": 25 }
اما در JSONP، پاسخ بهصورت زیر است:
callbackFunction({ "name": "Ali", "age": 25 });
این پاسخ:
JSON خالص نیست
بلکه یک کد جاوااسکریپت معتبر است
که هنگام لود شدن، اجرا میشود
1. سمت کلاینت
کلاینت یک تابع callback تعریف میکند:
function handleData(data) { console.log(data); }
سپس یک تگ اسکریپت میسازد:
<script src="https://api.example.com/data?callback=handleData">
سرور:
مقدار callback را از Query String میخواند
داده را داخل همان تابع میپیچد
و کد جاوااسکریپت برمیگرداند
handleData({ "name": "Ali", "age": 25 });
مرورگر:
فایل اسکریپت را دانلود میکند
کد را اجرا میکند
تابع callback اجرا میشود
داده در اختیار کلاینت قرار میگیرد
function showUser(user) { alert(user.name); } <script src="https://example.com/user?callback=showUser">
showUser({ "name": "Sara" });
راهحل هوشمندانهای بود، اما محدودیتهای جدی داشت:
فقط از متد GET پشتیبانی میکند
امکان ارسال Body وجود ندارد
مدیریت خطا (status code) ندارد
کنترل روی تایماوت و شکست درخواست سخت است
اجرای مستقیم کد از دامنهی خارجی
امکان تزریق کد مخرب
خطر بالای XSS
نیاز به اعتماد کامل به سرور مقابل
در واقع با JSONP، شما اجازه اجرای هر کدی را به یک دامنهی دیگر میدهید.

برداشت شخصی من از JSONP:
JSONP یک راهحل خلاقانه برای محدودیتهای قدیمی وب بود
بیشتر شبیه یک هک هوشمندانه عمل میکرد
یادگیری آن برای درک معماری مرورگر و تاریخ وب مهم است
اما در دنیای امروز، CORS راهحل استاندارد و امنتر است