שיתוף משאבים בין מקורות בצורה בטוחה
מדיניות המקור הזהה של הדפדפן חוסמת קריאת משאב ממקור אחר. המנגנון הזה מונע מאתרים זדוניים לקרוא נתונים של אתרים אחרים, אבל הוא גם מונע שימושים לגיטימיים.
אפליקציות אינטרנט מודרניות לרוב רוצות לקבל משאבים ממקור אחר, למשל אחזור נתוני JSON מדומיין אחר או טעינת תמונות מאתר אחר לרכיב <canvas>
. אלה יכולים להיות משאבים ציבוריים שצריכים להיות זמינים לקריאה לכולם, אבל מדיניות המקור הזהה חוסמת את השימוש בהם. בעבר, מפתחים השתמשו בפתרונות זמניים כמו JSONP.
שיתוף משאבים בין מקורות (CORS) פותר את הבעיה הזו בדרך סטנדרטית. הפעלת CORS מאפשרת לשרת לומר לדפדפן שהוא יכול להשתמש במקור נוסף.
איך פועלת בקשה לשימוש במשאבים באינטרנט?
דפדפן ושרת יכולים להחליף נתונים ברשת באמצעות Hypertext Transfer Protocol (HTTP). ב-HTTP מוגדרות כללי התקשורת בין מבצע הבקשה לבין מי שמשיב, כולל המידע הנדרש כדי לקבל משאב.
כותרת ה-HTTP מאפשרת לנהל משא ומתן על החלפת ההודעות בין הלקוח לשרת, ומשמשת לקביעת הגישה. גם הבקשה מהדפדפן וגם הודעת התגובה מהשרת מחולקות לכותרת ולגוף.
שם
מידע על ההודעה, כמו סוג ההודעה או הקידוד שלה. הכותרת יכולה לכלול מגוון מידע שמבוטא כצמדי מפתח/ערך. כותרת הבקשה וכותרת התשובה מכילות מידע שונה.
כותרת בקשה לדוגמה
Accept: text/html
Cookie: Version=1
הכותרת הזו זהה למשפט "אני רוצה לקבל HTML בתגובה. זה קובץ cookie שיש לי".
דוגמה לכותרת תשובה
Content-Encoding: gzip
Cache-Control: no-store
הכותרת הזאת מקבילה למילים "הנתונים בתגובה הזו מקודדים באמצעות gzip. אין לשמור במטמון".
גוף
ההודעה עצמה. זה יכול להיות טקסט רגיל, קובץ תמונה בינארי, קובץ JSON, קובץ HTML או פורמטים רבים אחרים.
איך פועל CORS
מדיניות המקור הזהה מנחה את הדפדפן לחסום בקשות ממקורות שונים. כשצריך משאב ציבורי ממקור אחר, השרת שמספק את המשאבים מורה לדפדפן שהמקור ששולח את הבקשה יכול לגשת למשאב שלו. הדפדפן זוכר את זה ומאפשר שיתוף משאבים בין מקורות למשאב הזה.
שלב 1: בקשה מהלקוח (הדפדפן)
כשהדפדפן שולח בקשה ממקורות שונים, הוא מוסיף כותרת Origin
עם המקור הנוכחי (הסכימה, המארח והיציאה).
שלב 2: תגובת השרת
כששרת רואה את הכותרת הזו, והוא רוצה לאפשר גישה, הוא מוסיף כותרת Access-Control-Allow-Origin
לתגובה עם ציון המקור של מבצע הבקשה (או *
כדי לאפשר גישה לכל מקור).
שלב 3: הדפדפן מקבל תשובה
כשהדפדפן רואה את התשובה הזו עם כותרת Access-Control-Allow-Origin
מתאימה, הוא משתף את נתוני התשובה עם אתר הלקוח.
שיתוף פרטי כניסה באמצעות CORS
מטעמי פרטיות, בדרך כלל משתמשים ב-CORS לבקשות אנונימיות, שבהן מגיש הבקשה לא מזוהה. אם רוצים לשלוח קובצי cookie כשמשתמשים ב-CORS, שיכולים לזהות את השולח, צריך להוסיף כותרות נוספות לבקשה ולתגובה.
בקשה
מוסיפים credentials: 'include'
לאפשרויות האחזור, כמו בדוגמה הבאה.
הבקשה כוללת את קובץ ה-cookie באופן הבא:
fetch('https://example.com', {
mode: 'cors',
credentials: 'include'
})
תשובה
צריך להגדיר את Access-Control-Allow-Origin
למקור ספציפי (ללא תו כללי לחיפוש באמצעות *
) ולהגדיר את Access-Control-Allow-Credentials
לערך true
.
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
בקשות קדם-הפעלה לקריאות HTTP מורכבות
כשאפליקציית אינטרנט שולחת בקשת HTTP מורכבת, הדפדפן מוסיף בקשה לפני הטיסה לתחילת שרשרת הבקשות.
במפרט CORS מוגדרת בקשה מורכבת באופן הבא:
- בקשה שמשתמשת ב-methods שאינן GET, POST או HEAD.
- בקשה שכוללת כותרות שאינן
Accept
,Accept-Language
אוContent-Language
. - בקשה עם כותרת
Content-Type
שאינהapplication/x-www-form-urlencoded
,multipart/form-data
אוtext/plain
.
הדפדפנים יוצרים באופן אוטומטי את כל הבקשות הנדרשות לקדם-הפעלה ושולחים אותן לפני הודעת הבקשה בפועל. בקשת קדם-ההפעלה היא בקשת OPTIONS
כמו הדוגמה הבאה:
OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE
בצד השרת, האפליקציה שמקבלת את הבקשה מגיבה לבקשת ההכנה מראש עם מידע על השיטות שהאפליקציה מקבלת מהמקור הזה:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS
תגובת השרת יכולה לכלול גם כותרת Access-Control-Max-Age
כדי לציין את משך הזמן בשניות שבו תוצאות בדיקת הקדם יישמרו במטמון. כך הלקוח יכול לשלוח מספר בקשות מורכבות בלי לחזור על בקשת הקדם-ההפעלה.