خطای CORS هنگام ارسال درخواست HTTP از یک منبع به منبع دیگر، رخ می دهد. در واقع گاها برخی از وب سایت ها منابع خود را از سرورهای متفاوت دریافت می کنند. منظور از منابع، مواردی چون تصویر، فایل های دانلودی، فیلم و … است. برای اینکه اطلاعات مذکور دریافت شوند، لازم است تا یک سری درخواست ها ارسال گردند. حال اگر این درخواست ها بررسی نشوند، در مرورگر شما خطای امنیتی مشاهده می شود. می توانید به کمک یکی از راه حل های ارائه شده در این مقاله، اقدام به رفع خطای CORS نمایید.
تصویر(1)
فهرست مطالب مقاله:
- CORS چیست؟
- چرا خطای CORS رخ می دهد؟
- نحوه رفع خطای CORS
- راه حل 1: Backend را برای ارائه دسترسی به CORS، پیکربندی کنید.
- راه حل 2: از یک سرور پروکسی استفاده کنید.
- راه حل 3: دور زدن خطا با استفاده از افزونه مرورگر
- اگر خطای CORS را برطرف نکنید، چه اتفاقی رخ می دهد؟
اگر شما یک توسعه دهنده وب هستید، احتمالا در حین کدنویسی، با خطای CORS برای یک API، مواجه شده اید. در زمان نگارش این مقاله حدود 13600 سوال در مورد خطای CORS در Stackoverflow پرسیده شده است. اگر این خطا را مشاهده نکرده اید، ممکن است در حین کدنویسی، با آن مواجه شوید. این ارور معمولاً یک پیغام خطا به صورت «Access to XMLHttpRequest has been blocked by CORS policy» است که به دنبال آن دلیلی مانند یکی از موارد زیر، مشاهده می شود:
- No ‘Access-Control-Allow-Origin’ header present
- No ‘Access-Control-Allow-Headers’ headers present
- Method not supported under Access-Control-Allow-Methods header
قبل از یافتن راه حل برای رفع خطا، باید بدانید که CORS چیست.
CORS چیست؟
Cross-Origin Resource Sharing یا CORS، به معنی "اشتراکگذاری اطلاعات بین منابع مختلف" است. CORS یک مکانیسم HTTP می باشد که امکان اشتراکگذاری اطلاعات بین یک منبع با منبع دیگر را به صورت امن فراهم میکند. این مکانیسم برای ساده سازی same-origin policy در مرورگرهای مدرن استفاده می شود. دو URL زمانی که پروتکلها، پورتها (در صورت وجود) یا میزبانهای متفاوتی داشته باشند، منبع متفاوتی نیز خواهند داشت.
تصویر(2)
به عنوان مثال، ارسال درخواست از https://example-a.com به https://example-b.com/api-1 به عنوان cross-origin در نظر گرفته می شود زیرا نام های میزبان متفاوتی دارند.
مرورگرها از قوانین same-origin پیروی کرده و درخواست های HTTP با cross-origin را که از اسکریپت ها ارسال می شوند، محدود می کنند. این بدان معنی است که یک وب سایت فقط مجاز به ارسال درخواست از منبع متعلق به خود است، مگر اینکه ارجاعات مرتبط با منابع دیگر، شامل هدرهای CORS مناسب باشند. هدرهای CORS در بخش بعدی این مقاله ذکر خواهند شد.
قوانین same-origin، یک سری موارد امنیتی برای جلوگیری از جعل درخواست بین سایتی (CSRF) هستند. بدون این قانون، یک وبسایت مخرب میتواند با ارسال درخواست HTTP، اطلاعات حساس شما را در وبسایت دیگری بخواند. قوانین same-origin، فقط اسکریپت های موجود در صفحه را از دسترسی به داده ها یا ارسال داده ها به منبعی دیگر، منع می کنند. اطلاعات دیگر مانند تصاویر و CSS، محدودیتی ندارند و از منابع دیگر در دسترس خواهند بود. برای دسترسی به داده ها از منابع دیگر یا ارسال داده به آنها، CORS مورد نیاز است.
چرا خطای CORS رخ می دهد؟
CORS از درخواست ها و انتقال داده ها بین مرورگرها و سرورهای cross-origin پشتیبانی می کند تا به صورت ایمن انجام شوند. همچنین متکی به مکانیزمی است که بررسی میکند آیا سرور نیز به درخواستهای منابع دیگر اجازه اجرا میدهد یا خیر، تا از ایمنی درخواست های cross-origin مطمئن شود.
تصویر(3)
هر زمان که یک وب سایت سعی می کند یک درخواست cross-origin ایجاد کند، مرورگر هدرهای CORS زیر را به درخواست اضافه می کند:
- Origin
- Access-Control-Request-Method
- Access-Control-Request-Headers
سرور پاسخی حاوی برخی از هدرهای CORS که در زیر آمده است، برای اجازه یا مسدود کردن درخواست، برمیگرداند:
- Access-Control-Allow-Origin
- Access-Control-Allow-Credentials
- Access-Control-Expose-Headers
- Access-Control-Max-Age
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
خطای CORS زمانی رخ می دهد که سرور هدرهای CORS مورد نیاز را برنگرداند.
به عنوان مثال، https://example-a.com سعی می کند تا یک درخواست API به https://example-b.com ارسال کند که اجازه دسترسی به منابع خود را ندهد. از آنجایی که https://example-a.com در هدر Access-Control-Allow-Origin پاسخ وجود ندارد، مرورگر یک خطای CORS را نمایش خواهد داد.
نحوه رفع خطای CORS
راه حل 1: Backend را برای ارائه دسترسی به CORS، پیکربندی کنید
اگر به Backend دسترسی دارید، میتوانید آن را طوری پیکربندی کنید که درخواستهای CORS را در صورت مجاز بودن، انجام دهد. شرط اساسی این است که Access-Control-Allow-Origin را به سربرگ پاسخ اضافه کنید تا منبعی که اجازه دسترسی به منابع سرور را دارد، مشخص نمایید.
میتوانید Backend را طوری پیکربندی کنید که مقدار زیر را در هدر پاسخ بازگرداند:
Access-Control-Allow-Origin: https://example-a.com
این کد به https://example-a.com اجازه میدهد تا یک درخواست cross-origin به سرور شما ارسال کند. با این حال، فقط می توان یک منبع اضافه کرد. اگر میخواهید چندین منبع را مجاز کنید، میتوانید با خواندن هدر Origin از درخواست، مقدار آن را به صورت پویا و با مقدار Access-Control-Allow-Origin تنظیم کنید.
روش دیگر، تنظیم هدر روی * : Access-Control-Allow-Origin برای اجازه دسترسی به درخواست های دریافتی از تمامی URL ها است. با این حال، هنگام استفاده از آن باید مراقب باشید زیرا ممکن است سرور شما را در برابر حملات CSRF آسیب پذیر کند. اگر از یک سرویس API خارجی استفاده میکنید و نمیتوانید Backend را برای پذیرش درخواستهای CORS پیکربندی نمایید، میتوانید یکی از روشهایی که در ادامه آمده است را امتحان نمایید.
راه حل 2: از یک سرور پروکسی استفاده کنید
از آنجایی که قوانین یکسانی توسط مرورگرهای اینترنتی اجرا می شوند اما در ارتباط سرور به سرور اینگونه نیست، می توانید از یک سرور پروکسی برای فراخوانی API خارجی استفاده کنید.
یک سرور پروکسی به عنوان یک middleware یا "میان افزار" بین سیستم کاربر و سرور عمل می کند. به جای ارسال درخواست مستقیم از سیستم کاربر به API خارجی، می توانید درخواست را به سرور پروکسی ارسال کنید. سرور پروکسی، یک درخواست به API خارجی به جای شما ارسال کرده و پاسخی را که از API خارجی دریافت می کند، برمی گرداند.
اگر سرور API خارجی، هدرهای HTTP مطابق با استاندارد CORS را برنگرداند، خطای CORS رخ میدهد. میتوانید هدر از دست رفته ای مانند * : Access-Control-Allow-Origin را به درخواست اضافه کنید و پاسخ را با استفاده از یک سرور پروکسی، به مرورگر برگردانید.
تصویر(4)
می توانید سرور پروکسی مختص به خود را ایجاد نموده یا از یک سرور پروکسی CORS مانند CORS Anywhere برای دریافت داده ها از API خارجی، استفاده کنید. نکته ای که باید به آن توجه داشت این است که سرور پروکسی CORS Anywhere، اشتراکی بوده و امکان دارد گاهی اوقات کمی کند باشد. اگر نیاز به ارتباط مداوم با API خارجی دارید، ایجاد سرور پروکسی اختصاصی، گزینه بهتری خواهد بود.
راه حل 3: دور زدن خطا با استفاده از افزونه مرورگر
این روش، راه حل مناسبی برای رفع خطا نیست زیرا فقط در رایانه شما که افزونه را نصب کرده اید، کارایی دارد. با این حال، می توانید از این روش زمانی که در طول کدنویسی نیاز به ارسال درخواست cross-origin دارید، استفاده نمایید. برای رفع خطای CORS، می توانید یک افزونه مرورگر مانند CORS Unblock را دانلود کنید. این افزونه هنگامی که فعال است، هدر * : Access-Control-Allow-Origin را به تمامی پاسخ های HTTP اضافه می کند. همچنین میتواند هدرهای Access-Control-Allow-Origin و Access-Control-Allow-Methods دلخواه را به پاسخها بیافزاید.
این روش رفع خطای CORS، مانند استفاده از یک سرور پروکسی CORS است که در بالا ذکر شد اما این روش فقط روی رایانه ای که افزونه را نصب نموده، کارایی دارد.
اگر خطای CORS را برطرف نکنید، چه اتفاقی رخ می دهد؟
تمامی API ها نمی توانند توسط کاربر استفاده شوند. برخی از APIها مانند Google Maps Places API، برای سرور طراحی شده اند. اگر سعی کنید از سیستم کاربر به API دسترسی پیدا کنید، یک خطای CORS دریافت خواهید کرد:
تصویر(5)
اگرچه میتوانید به کمک یکی از راهحلهای بالا، خطا را رفع کنید اما Google به توسعهدهندگان توصیه میکند که از راهنمای Google Map Places استفاده کنند. بسیاری از API های دیگر نیز راهنمای کاربر را ارائه میکنند تا مشکلات توسعهدهندگان را برای پیادهسازی عملکردهای متفرقه در برنامههایشان، کاهش دهند. به عنوان مثال، Bannerbear دارای راهنمای کاربر برای Ruby ،Node.js و PHP است تا توسعه دهندگان به راحتی بتوانند API تولید تصویر را در نرم افزارهای خود به کار ببرند.