กลไกการแชร์ทรัพยากรข้ามโดเมน (CORS)

แชร์ทรัพยากรข้ามโดเมนอย่างปลอดภัย

Mariko Kosaka

นโยบายต้นทางเดียวกันของเบราว์เซอร์จะบล็อกการอ่านทรัพยากรจากต้นทางอื่น กลไกนี้จะป้องกันไม่ให้เว็บไซต์ที่เป็นอันตรายอ่านข้อมูลของเว็บไซต์อื่นๆ แต่ก็จะป้องกันการใช้งานที่ถูกต้องด้วย

เว็บแอปสมัยใหม่มักต้องการรับทรัพยากรจากแหล่งที่มาอื่น เช่น การดึงข้อมูล 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

คำขอการตรวจสอบล่วงหน้าสำหรับการเรียกใช้ HTTP ที่ซับซ้อน

เมื่อเว็บแอปส่งคําขอ HTTP ที่ซับซ้อน เบราว์เซอร์จะเพิ่มคําขอก่อนเข้าสู่โหมดเที่ยวบินไว้ที่จุดเริ่มต้นของเชนคําขอ

ข้อกำหนด CORS กำหนดคำขอที่ซับซ้อนไว้ดังนี้

  • คำขอที่ใช้เมธอดอื่นที่ไม่ใช่ 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 เพื่อระบุระยะเวลาเป็นวินาทีในการแคชผลการค้นหาก่อนแสดงผลได้ด้วย ซึ่งช่วยให้ไคลเอ็นต์ส่งคำขอที่ซับซ้อนหลายรายการได้โดยไม่ต้องส่งคำขอช่วงก่อนเข้าสู่โหมดใช้งานซ้ำ