เผยแพร่เมื่อ: 5 พฤศจิกายน 2018
นโยบายแหล่งที่มาเดียวกันของเบราว์เซอร์จะบล็อกการอ่านทรัพยากรจากแหล่งที่มาอื่น กลไกนี้จะหยุดไม่ให้เว็บไซต์ที่เป็นอันตรายอ่านข้อมูลของเว็บไซต์อื่น แต่ก็ป้องกันการใช้งานที่ถูกต้องด้วย
เว็บแอปสมัยใหม่มักต้องการรับทรัพยากรจากแหล่งที่มาอื่น เช่น ดึงข้อมูล JSON จากโดเมนอื่น หรือโหลดรูปภาพจาก
เว็บไซต์อื่นลงในองค์ประกอบ <canvas> ทรัพยากรเหล่านี้อาจเป็นทรัพยากรสาธารณะที่ทุกคนควรจะอ่านได้ แต่นโยบายแหล่งที่มาเดียวกันจะบล็อกการใช้งาน นักพัฒนาแอปจึงใช้โซลูชันชั่วคราว เช่น
JSONP มาโดยตลอด
กลไกการแชร์ทรัพยากรข้ามโดเมน (CORS) แก้ไขปัญหานี้ด้วยวิธีที่ได้มาตรฐาน การเปิดใช้ CORS จะช่วยให้เซิร์ฟเวอร์บอกเบราว์เซอร์ได้ว่าสามารถใช้แหล่งที่มาเพิ่มเติมได้
คำขอทรัพยากรทำงานอย่างไรบนเว็บ
เบราว์เซอร์และเซิร์ฟเวอร์สามารถแลกเปลี่ยนข้อมูลผ่านเครือข่ายโดยใช้ Hypertext Transfer Protocol (HTTP) HTTP กำหนดกฎการสื่อสารระหว่างผู้ขอและผู้ตอบ รวมถึงข้อมูลที่จำเป็นในการรับทรัพยากร
ส่วนหัว HTTP จะเจรจาการแลกเปลี่ยนข้อความระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ และใช้เพื่อกำหนดสิทธิ์เข้าถึง ทั้งคำขอของเบราว์เซอร์และข้อความตอบกลับของเซิร์ฟเวอร์จะแบ่งออกเป็น ส่วนหัว และ เนื้อความ
ส่วนหัว
ข้อมูลเกี่ยวกับข้อความ เช่น ประเภทของข้อความหรือการเข้ารหัสของข้อความ ส่วนหัวอาจมี ข้อมูลหลากหลายรูปแบบ ที่แสดงเป็นคู่คีย์-ค่า ส่วนหัวของคำขอและส่วนหัวการตอบกลับจะมีข้อมูลที่แตกต่างกัน
ตัวอย่างส่วนหัวของคำขอ
Accept: text/html
Cookie: Version=1
ส่วนหัวนี้เทียบเท่ากับการพูดว่า "ฉันต้องการรับ HTML ในการตอบกลับ นี่คือคุกกี้ที่ฉันมี"
ตัวอย่างส่วนหัวการตอบกลับ
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 จะใช้สำหรับคำขอที่ไม่ระบุตัวตน ซึ่งจะไม่ระบุตัวตนของผู้ขอ เนื่องจากเหตุผลด้านความเป็นส่วนตัว หากต้องการส่งคุกกี้เมื่อใช้ CORS ซึ่งระบุตัวตนของผู้ส่งได้ คุณต้องเพิ่มส่วนหัวเพิ่มเติมในคำขอและการตอบกลับ
ส่งคำขอ
เพิ่ม credentials: 'include' ลงในตัวเลือกการดึงข้อมูลตามตัวอย่างต่อไปนี้
ซึ่งจะรวมคุกกี้ไว้ในคำขอ ดังนี้
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
คำขอ Preflight สำหรับการเรียก HTTP ที่ซับซ้อน
เมื่อเว็บแอปส่งคำขอ HTTP ที่ซับซ้อน เบราว์เซอร์จะเพิ่ม คำขอ Preflight ที่จุดเริ่มต้นของห่วงโซ่คำขอ
ข้อกำหนด CORS กำหนด คำขอที่ซับซ้อน ไว้ดังนี้
- คำขอที่ใช้เมธอดอื่นนอกเหนือจาก GET, POST หรือ HEAD
- คำขอที่มีส่วนหัวอื่นนอกเหนือจาก
Accept,Accept-LanguageหรือContent-Language - คำขอที่มีส่วนหัว
Content-Typeอื่นนอกเหนือจากapplication/x-www-form-urlencoded,multipart/form-dataหรือtext/plain
เบราว์เซอร์จะสร้างคำขอ Preflight ที่จำเป็นโดยอัตโนมัติและส่งคำขอดังกล่าวก่อนข้อความคำขอจริง คำขอ Preflight เป็นคำขอ OPTIONS เช่น ตัวอย่างต่อไปนี้
OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE
ในฝั่งเซิร์ฟเวอร์ แอปที่ได้รับคำขอจะตอบกลับคำขอ Preflight ด้วยข้อมูลเกี่ยวกับเมธอดที่แอปพลิเคชันยอมรับจากแหล่งที่มานี้
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS
การตอบกลับของเซิร์ฟเวอร์อาจมีส่วนหัว Access-Control-Max-Age เพื่อระบุระยะเวลาเป็นวินาทีในการแคชผลลัพธ์ Preflight ซึ่งจะช่วยให้ไคลเอ็นต์ส่งคำขอที่ซับซ้อนหลายรายการได้โดยไม่ต้องส่งคำขอ Preflight ซ้ำ