לעתים קרובות אנו נתקלים במצב שבו יישום פרונטאנד ב-app.example.com שולח בקשות ל-API ב-api.example.com (או לשיטות REST של Bitrix24), והדפדפן חוסם את הבקשה עקב CORS. כאב קלאסי: מפתח מבזבז שעות בחיפוש אחר השגיאה, אף על פי שהבעיה נפתרת על ידי הוספת שלושה כותרות. הגדרת CORS אינה נועדה להגן על השרת (בקשות מצד השרת אינן מושפעות מ-CORS), אלא לאפשר ל-JavaScript שלך לעבוד עם בקשות חוצות-מקור (cross-origin). במשך יותר מ-10 שנות עבודה עם Bitrix, פתרנו בעיות CORS עבור יותר מ-200 פרויקטים, וחסכנו ללקוחות בממוצע 200–400 דולר על ניפוי שגיאות.
כיצד פועלות בקשות CORS
CORS (Cross-Origin Resource Sharing) הוא מנגנון אבטחה של הדפדפן שחוסם בקשות לדומיין שונה מדומיין הדף. בקשות פשוטות (GET, POST עם Content-Type: application/x-www-form-urlencoded) נשלחות ישירות על ידי הדפדפן, אך הוא בודק את התשובה: אם אין כותרת Access-Control-Allow-Origin עם הערך הנכון, JavaScript לא מקבל את התשובה (הבקשה נשלחה, השרת ענה, אך הדפדפן הסתיר אותה מ-JS). בקשות Preflight מיועדות לשיטות לא סטנדרטיות (PUT, DELETE, PATCH) ולכותרים (Authorization, Content-Type: application/json). הדפדפן שולח תחילה בקשת OPTIONS ("האם אני יכול לעשות זאת?"), השרת עונה—ורק אז הדפדפן שולח את הבקשה בפועל.
מתי נדרשת בקשת Preflight?
כל בקשה עם Content-Type שאינו application/x-www-form-urlencoded, כגון application/json, או עם כותרת מותאמת אישית (לדוגמה, X-API-Key) גורמת ל-preflight. Preflight מתרחשת גם בעת שימוש בשיטות שאינן GET/POST. חשוב לקחת תכונה זו בחשבון בעת תכנון REST API—אם הלקוח שלך שולח JSON, היה מוכן לטפל ב-OPTIONS.
כיצד להגדיר CORS על Nginx
עבור API של Bitrix המותקן מקומית (on-premise), עדיף להגדיר CORS ב-Nginx, לא ב-PHP. Nginx מטפל ב-preflight של OPTIONS מבלי להפעיל PHP, מה שמעניק שיפור ביצועים של עד 15 אלפיות השנייה לבקשה.
location /api/ { # Список разрешённых источников set $cors_origin ""; if ($http_origin ~* "^https://(app\.example\.com|admin\.example\.com)$") { set $cors_origin $http_origin; } # Preflight OPTIONS if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin $cors_origin always; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PATCH, OPTIONS" always; add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-API-Key" always; add_header Access-Control-Max-Age 3600 always; add_header Content-Length 0; return 204; } add_header Access-Control-Allow-Origin $cors_origin always; add_header Access-Control-Allow-Credentials true always; proxy_pass http://php_backend; } location /api/ { # Список разрешённых источников set $cors_origin ""; if ($http_origin ~* "^https://(app\.example\.com|admin\.example\.com)$") { set $cors_origin $http_origin; } # Preflight OPTIONS if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin $cors_origin always; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PATCH, OPTIONS" always; add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-API-Key" always; add_header Access-Control-Max-Age 3600 always; add_header Content-Length 0; return 204; } add_header Access-Control-Allow-Origin $cors_origin always; add_header Access-Control-Allow-Credentials true always; proxy_pass http://php_backend; } נדרש אם הבקשות נושאות עוגיות (סשנים של Bitrix). במקרה זה, Access-Control-Allow-Credentials: true לא יכול להיות Access-Control-Allow-Origin—רק דומיין ספציפי.
הגדרה דרך PHP (init.php או middleware)
אם יש צורך להגדיר CORS דינמית (כללים שונים עבור נקודות קצה שונות, רשימת מקורות ממסד נתונים):
// /local/php_interface/init.php или middleware API $allowedOrigins = ['https://app.example.com', 'https://admin.example.com']; $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; if (in_array($origin, $allowedOrigins)) { header('Access-Control-Allow-Origin: ' . $origin); header('Access-Control-Allow-Credentials: true'); header('Vary: Origin'); // Важно для корректного кеширования CDN } if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS'); header('Access-Control-Allow-Headers: Authorization, Content-Type, X-API-Key'); header('Access-Control-Max-Age: 3600'); http_response_code(204); exit; } הכותרת * היא חובה עם CORS דינמית—MDN Web Docs ממליצים עליה לאחסון CDN תקין.
CORS עבור REST API של Bitrix24
לא ניתן להגדיר את Bitrix24 בענן—כותרות CORS מנוהלות בצד של Bitrix. עבור בקשות דפדפן ל-// /local/php_interface/init.php или middleware API $allowedOrigins = ['https://app.example.com', 'https://admin.example.com']; $origin = $_SERVER['HTTP_ORIGIN'] ?? ''; if (in_array($origin, $allowedOrigins)) { header('Access-Control-Allow-Origin: ' . $origin); header('Access-Control-Allow-Credentials: true'); header('Vary: Origin'); // Важно для корректного кеширования CDN } if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS'); header('Access-Control-Allow-Headers: Authorization, Content-Type, X-API-Key'); header('Access-Control-Max-Age: 3600'); http_response_code(204); exit; } , השתמש ב-JS-SDK המובנה (Vary: Origin), שעובד בתוך יישום iframe ואינו כפוף למגבלות CORS. בקשות REST ישירות מהדפדפן לדומיין Bitrix24 אחר דורשות פרוקסי דרך השרת שלך. פרטים נוספים בתיעוד הרשמי.
מדוע לא ניתן להשתמש ב-portal.bitrix24.ru/rest/ עם Credentials?
BX24.callMethod מאפשר לכולם. אך עם *, הדבר אסור—הדפדפן יחסום תשובה כזו. רק דומיינים ספציפיים מותרים.
אמת את רשימת המקורות. בדיקה כמו Access-Control-Allow-Origin: * אינה נעקפת על ידי תוקף עם כותרת Access-Control-Allow-Credentials: true. לא—זו אינה עקיפה: CORS מגן מפני התקפות דפדפן, לא מפני curl. בקשות מצד השרת מתעלמות מ-CORS.
מטמון Preflight (if ($origin === 'https://app.example.com')). ערך של 3600 אומר שהדפדפן לא שולח בקשת OPTIONS חוזרת במשך שעה. ערך גדול מדי מאט את זיהוי השינויים במדיניות CORS.
תרחישים אופייניים הדורשים הגדרת CORS
| תרחיש | המלצה |
|---|---|
| פרונטאנד באותו דומיין | CORS לא נדרש |
פרונטאנד בתת-דומיין (Origin: https://app.example.com → Max-Age) |
CORS עם מקור ספציפי |
| API ציבורי לשותפים | CORS app.example.com (ללא credentials) |
| יישום נייד (לא דפדפן) | CORS לא נדרש, הבקשות הן מצד השרת |
| לקוחות פרונטאנד מרובים | רשימה דינמית + Vary: Origin |
כיצד לפתור שגיאות CORS נפוצות
| שגיאה | סיבה | פתרון |
|---|---|---|
api.example.com |
הכותרת לא נשלחה או אי-התאמה במקור | הוסף כותרת עם המקור הנכון |
* |
בקשת OPTIONS לא קיבלה תשובה נכונה | טפל ב-OPTIONS, החזר 200 או 204 עם כותרות |
No 'Access-Control-Allow-Origin' |
כותרת מותאמת אישית לא מותרת | הוסף כותרת ל-Response to preflight request doesn't pass access control check |
Request header field X-API-Key is not allowed by Access-Control-Allow-Headers |
השיטה לא מותרת | הרחב את רשימת השיטות ב-preflight |
מה כלול בעבודה
- ביקורת על הגדרת CORS הנוכחית וזיהוי בעיות—95% מהבעיות מזוהות תוך 30 דקות.
- הגדרת CORS על Nginx או Apache (בהתאם לסביבה).
- יישום CORS דינמית דרך PHP (אם נדרש).
- פיתוח שרת פרוקסי עבור Bitrix24 REST (אם יש צורך).
- בדיקת כל התרחישים (פשוט, preflight, עם credentials)—בממוצע 8 מקרי בדיקה.
- תיעוד והמלצות לתמיכה שוטפת.
כיצד להגדיר CORS: מדריך שלב-אחר-שלב
- קבע את רשימת המקורות המותרים.
- בחר את שיטת ההגדרה: Nginx (סטטי) או PHP (דינמי).
- הוסף טיפול בבקשות OPTIONS עם הכותרות הנדרשות.
- הגדר
Access-Control-Allow-Headersעבור בקשות עם סשנים. - בדוק באמצעות curl או כלי פיתוח של הדפדפן.
הגדרת CORS היא 30 דקות של עבודה עם הבנה נכונה של המנגנון. רוב בעיות CORS נפתרות על ידי מיקום נכון של כותרות (לפני פלט גוף התשובה) וטיפול נכון בבקשות OPTIONS. אם אתה רוצה להימנע משעות של ניפוי שגיאות, הפקיד משימה זו בידי אנשי מקצוע. צור קשר כדי לקבל ייעוץ לפרויקט שלך. אנו מבטיחים שאחרי ההגדרה, ה-API שלך יעבוד כראוי עם כל לקוחות הדפדפן.







