ทำความรู้จักกับ CORS และใช้งานอย่างไรให้ไม่เจอ Error

หากคุณกำลังพัฒนาเว็บแอปที่ต้องเรียก API ข้ามโดเมน แล้วเจอข้อความประมาณว่า “Access to fetch at ‘https://api.example.com/data’ from origin ‘https://yourdomain.com’ has been blocked by CORS policy” อย่าเพิ่งรีบตกใจไป เพราะนี่คือปัญหาสุดคลาสสิกที่เรียกว่า CORS หรือ Cross-Origin Resource Sharing ซึ่งในบทความนี้เราจะพาไปทำความรู้จักและเข้าใจมันแบบง่าย ๆ กัน

CORS คืออะไร?

CORS ย่อมาจาก Cross-Origin Resource Sharing คือกลไกความปลอดภัยของเว็บเบราว์เซอร์ที่ใช้ควบคุมการเข้าถึงทรัพยากร (เช่น API, ไฟล์ JSON, รูปภาพ ฯลฯ) ระหว่างต้นทาง (Origin) อื่น ว่าอนุญาตให้เว็บไซต์อื่นมาขอข้อมูลจากตัวเองหรือไม่ โดยต้นทาง (Origin) ในมุมมองของเว็บเบราว์เซอร์จะประกอบไปด้วย 3 ส่วน ได้แก่ Protocol, Hostname และ Port

ตัวอย่างของ Origin

URLOrigin
https://example.comhttps://example.com:443
http://example.comhttp://example.com:80
https://api.example.comคนละ origin เพราะ subdomain ต่างกัน
https://example.com:3000คนละ origin เพราะ port ต่างกัน

ดังนั้น ถ้าเว็บของเรารันที่ https://myapp.com แล้วเรียก API จาก https://api.myapp.com ก็ถือว่าเป็น cross-origin แล้ว

ทำไมถึงต้องมี CORS?

สาเหตุหลักที่ CORS ถูกพัฒนาขึ้นมา ก็เพื่อเพิ่มความปลอดภัยในการใช้งานเว็บไซต์ โดยเฉพาะการป้องกันภัยคุกคามที่อาจเกิดจากเว็บภายนอก เช่น การขโมยข้อมูลส่วนตัว การโจมตีแบบ Cross-Site Request Forgery (CSRF) หรือการแอบใช้ session/cookie ของผู้ใช้โดยไม่ได้รับอนุญาต ทางเบราว์เซอร์จึงมีระบบป้องกันไม่ให้เว็บไซต์ใด ๆ สามารถเรียกดูหรือใช้งานข้อมูลจากอีกเว็บหนึ่งได้ทันที เว้นเสียแต่ว่าเว็บปลายทางจะระบุชัดเจนว่าอนุญาต

ยกตัวอย่างเช่น มีผู้ใช้ล็อกอินเข้าเว็บธนาคารที่ bank.com แล้วอยู่ ๆ ก็มีเว็บแปลก ๆ ที่ hacker.com แอบฝัง JavaScript ไว้ และพยายามขอข้อมูลจาก bank.com โดยถ้าไม่มี CORS คอยกรองไว้ แฮกเกอร์อาจดูดข้อมูลสำคัญของผู้ใช้ไปได้เลย

การทำงานของ CORS (เบื้องหลัง)

สมมุติว่าเว็บไซต์ A (https://app-client.com) พยายามเรียก API จากเว็บไซต์ B (https://api-server.com) ซึ่งเป็น Cross-Origin โดยเมื่อเบราว์เซอร์เจอการร้องขอดังกล่าว จะเริ่มดำเนินการตามขั้นตอนต่อไปนี้

1. เบราว์เซอร์ส่งคำขอ HTTP request ไปที่ https://api-server.com

2. ฝั่ง API Server จะตรวจสอบและตอบกลับ Header ของคำขอ เช่น

เพิ่ม app-client.com ให้เข้าถึงได้

Access-Control-Allow-Origin: https://app-client.com

หรือยอมให้ทุก Origin เข้าถึงได้ (ไม่แนะนำกับข้อมูลที่ต้องการความปลอดภัย)

Access-Control-Allow-Origin: *

3. หากเบราว์เซอร์ไม่เห็น Header เหล่านี้ เบราว์เซอร์จะดำเนินการบล็อกคำขอนั้นทันที

การเปิดใช้งาน CORS

ฝั่งเซิร์ฟเวอร์

ตัวอย่างใน Node.js (Express)

const express = require('express');
const cors = require('cors');
const app = express();

app.use(cors({
  origin: 'https://yourdomain.com' // หรือใช้ '*' ถ้าไม่ซีเรียส
}));

ตัวอย่างใน PHP

const express = require('express');
const cors = require('cors');
const app = express();

app.use(cors({
  origin: 'https://yourdomain.com' // หรือใช้ '*' ถ้าไม่ซีเรียส
}));

ตัวอย่างใน nginx

header("Access-Control-Allow-Origin: https://yourdomain.com");

ฝั่ง Frontend

ไม่มีอะไรต้องตั้งค่าเป็นพิเศษ แค่ตั้งให้ส่ง request ตามปกติ

fetch('https://api.example.com/data')
  .then(res => res.json())
  .then(data => console.log(data));

ถ้ามี Header พิเศษ เช่น Authorization หรือ Content-Type ที่ไม่ใช่ค่าเริ่มต้น เบราว์เซอร์จะส่ง preflight request (OPTIONS) ก่อน เพื่อเช็กว่าฝั่ง server อนุญาตมั้ย

ปัญหาและความเข้าใจผิดที่พบได้บ่อยเกี่ยวกับ CORS

  • ปัญหา Access-Control-Allow-Origin missing → เกิดจาก Server ไม่ได้ตั้ง header ตอบกลับ
  • ปัญหา CORS policy: No ‘Access-Control-Allow-Origin’ header → เกิดจากฝั่งเบราว์เซอร์บล็อกทันที
  • ❌ คิดว่าเป็นปัญหาจากฝั่ง client → ✅ เป็นเรื่องของ server ที่ต้องอนุญาตเท่านั้น.
  • ❌ คิดว่าใช้ * กับ credential (cookie/token) ได้ → ✅ ต้องระบุ origin ให้ชัดเจน

จัดการ CORS ยังไงให้เวิร์ก

  • อย่าใช้ * กับ API ที่ต้องมี Auth (เพราะจะใช้ร่วมกับ credentials ไม่ได้)
  • ถ้าใช้ fetch แบบมี cookie หรือ token ต้องตั้ง
fetch(url, {
  credentials: 'include'
})

แล้วฝั่ง server ต้องตอบด้วย

Access-Control-Allow-Credentials: true
  • ระวัง environment ที่ต่างกัน (เช่น dev, staging, prod) โดยต้องกำหนด Origin ให้ถูกต้อง

สรุปง่าย ๆ คือ CORS เปรียบเสมือนการ์ดรักษาความปลอดภัยของเว็บเบราว์เซอร์ ที่จะคอยถาม server ว่าเว็บนี้จะเข้ามาเอาข้อมูลได้หรือไม่ ถ้า server ไม่ตอบหรือไม่อนุญาตอย่างชัดเจน เบราว์เซอร์ก็จะไม่ให้ข้อมูลนั้นถูกใช้งานในฝั่ง client เลย เป็นการป้องกันแบบเชิงรุกที่ช่วยให้ผู้ใช้งานเว็บปลอดภัยมากขึ้น

Was this article helpful?

Related Articles