โดยปกติแล้วมือใหม่หัดทำ API แล้วเอาหน้าเว็บไปต่อมักจะเจอปัญหาข้อมูลไม่มา สงสัยว่า API เป็นอ
ะไรหรือป่าว? พอไปเปิด console ในฝั่งของ client ดูก็พบว่ามี Error ประมาณว่าติด CORS หรือ Cross-Origin Resource Sharing ซึ่งในวันนี้เราจะมาหาคำตอบกันว่า CORS มันคืออะไร? ทำงานยังไง? มีอะไรที่เราต้องตั้งค่าหรือกำหนดบ้าง? พร้อมตัวอย่างการใช้งานคู่กับ Node.js อีกด้วย!
CORS คืออิหยัง?
CORS ย่อมาจาก Cross-Origin Resource Sharing หมายถึง กลไกที่ช่วยให้เว็บแอปพลิเคชันสามารถดึงข้อมูลหรือทรัพยากรจากเว็บเซิร์ฟเวอร์อื่นได้ โดยปกติแล้ว เว็บแอปจะดึงข้อมูลจากเซิร์ฟเวอร์เดียวกันเท่านั้น แต่ CORS ช่วยให้เราข้ามข้อจำกัดนี้ได้
หากเปรียบกับร้านอาหารร้านนึง เช่น ร้านส้มตำ ที่มีโซนครัว (Back-End) ส่วนที่นั่งทานของลูกค้า (Front-End) ชื่อร้านก็คือโดเมน แล้วลูกค้าต้องการสั่งชาเย็นของร้านข้างๆ มากิน แต่ร้านข้างๆ เนี่ยไม่อนุญาตเพราะยังไม่รู้จักกับเจ้าของร้านส้มตำ ยังไม่ไว้วางใจ เลยไม่สามารถส่งของที่ลูกค้าต้องการมาได้
ซึ่งแน่นอนว่าหากเราอยากให้ สามารถเรียกสิ่งที่ลูกค้าต้องการได้ทั้งสองร้านต้องทำความรู้จักกันก่อนถึงจะเรียกข้ามกันได้ ! โดยเมื่อเราเข้าใจ Concept เรื่องการเรียกข้ามโดเมนแล้ว เดี๋ยวเรามาดูกันต่อว่าแล้วอะไรบ้างที่จะทำให้เกิด CORS Error ผ่านการทำงานของ CORS
CORS ทำงานยังไง?
จากที่เราได้รู้จักกับ CORS กันไปแล้ว จะเห็นได้ว่า ตามปกติแล้ว เว็บไซต์ A จะไม่สามารถดึงข้อมูลจากเว็บไซต์ B โดยตรงได้ นี่คือสิ่งที่เรียกว่า Same-Origin Policy ทำให้เว็บไม่สามารถ fetch ข้อมูลจาก URL ภายนอกมาได้
เราสามารถตั้งค่า CORS ใน Node.js ได้เพื่อให้ Browser รู้ว่า origin ไหนที่สามารถส่ง request ไปเอา resource มาได้ โดยเราสามารถระบุใน Access-Control-Allow-Origin header ในฝั่งของ Server ได้
วิธีการตั้งค่า CORS ใน Node.js
เพื่อให้เข้าใจถึงการตั้งค่า CORS ใน Node.js เราจะใช้ Express framework มาช่วยในการจัดการ requests และ responses ระหว่าง front-end และ back-end
เปิด Terminal หรือ Command Prompt แล้วสร้างโฟลเดอร์โปรเจกต์
mkdir my-cors-project
cd my-cors-project
สร้างโปรเจกต์ Node.js พร้อมไฟล์ package.json แบบ default
npm init -y
จากนั้นมาสร้างไฟล์ server.js
const express = require("express");
const app = express();
const PORT = 3000;
app.get("/api/data", (req, res) => {
res.json({ message: "Hello, CORS!" });
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
รันโปรแกรมด้วยคำสั่ง node server.js
ต่อมาเราจะมาสร้างไฟล์หน้าเว็บแบบง่ายๆ ในการเรียกข้อมูลจาก localhost:3000/api/data ไปแสดง โดยสร้างไฟล์ index.html ขึ้นพร้อม fetch ข้อมูลมาจาก API
<!DOCTYPE html>
<html>
<head>
<title>CORS Test</title>
</head>
<body>
<div id="data"></div>
<script>
fetch("http://localhost:3000/api/data")
.then((response) => response.json())
.then((data) => {
document.getElementById("data").innerText = data.message;
})
.catch((error) => {
console.error("Error:", error);
});
</script>
</body>
</html>
แล้วทำการติดตั้ง “Live server” และรันเว็บผ่าน live server จะเห็นได้ว่าหน้าเว็บเรารันอยู่ที่ localhost:5500 ซึ่งเป็นคนละ Port กับ API
เมื่อ Port ไม่ตรงกัน! ก็ถือว่าบ่ใช่ origin เดียวกันแล้วหนา ซึ่งสิ่งที่ต้องระบุให้ตรงกันใน URL จะต้องมี 3 ส่วนด้วยกันคือ
1. scheme เช่น HTTP, HTTPS
2. domain เช่น localhost, www.borntodev.com
3. port เช่น 3000, 5500
เมื่อเราลองรันหน้าเว็บมาแล้วก็ให้ทำการเปิด console ดูก็จะพบว่า Error ที่เราตามหา ก็มาแล้วจ้าาา
วิธีกำหนด CORS ให้มันใช้ได้
ใน Node.js สามารถติดตั้ง CORS packages ด้วยคำสั่ง
npm install cors
เรียกใช้งาน CORS ด้วยคำสั่ง const cors = require(“cors”); และ ใช้ CORS middleware แบบอนุญาตทั้งหมด
ใช้ CORS middleware แบบอนุญาตทั้งหมด
const express = require("express");
const cors = require("cors");
const app = express();
// ใช้ CORS middleware แบบอนุญาตทั้งหมด
app.use(cors());
const PORT = 3000;
app.get("/api/data", (req, res) => {
res.json({ message: "Hello, CORS!" });
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
แบบนี้ผลลัพธ์ก็จะมาแล้ว หน้าบ้านก็สามารถเรียก API ต่างถิ่นมาแสดงได้ แต่ๆ ถ้าใช้ท่านี้ API นี้เว็บไหนก็เรียก API ไปใช้ได้ เพราะอนุญาตให้หมดทุกที่ ทุก Path
ใช้งานแบบกำหนดโดเมน
เราสามารถใส่ origin เข้าไปใน cors ได้เพื่อกำหนดว่าเราจะอนุญาตโดเมนไหนใช้งานได้บ้าง
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors({ origin: "http://127.0.0.1:5500" }));
const PORT = 3000;
app.get("/api/data", (req, res) => {
res.json({ message: "Hello, CORS!" });
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
เมื่อเรารันเว็บผ่าน Live Server ที่ 127.0.0.1:5500 จะเห็นว่าเว็บใช้งานได้ แต่หน้าเว็บที่เปิดผ่าน Path หรือโดเมนอื่นจะไม่สามารถเข้าถึง API ได้
ใช้งานเฉพาะบาง route
หากเราต้องการให้ใช้ได้เฉพาะบาง Route เราก็สามารถใส่ cors() ลงไปใน route ที่ต้องการและภายใน route ก็สามารถกำหนด origin ได้เช่นกัน
const express = require('express');
const cors = require('cors');
const app = express();
const PORT = 3000
// สร้าง API route ที่อนุญาตเฉพาะจาก 'http://yourdomain.com'
app.get('/api/data', cors({ origin: 'http://yourdomain.com' }), (req, res) => {
res.json({ message: 'Hello, CORS!' });
});
// สร้าง API route ที่อนุญาตทั้งหมด
app.get('/api/open', cors(), (req, res) => {
res.json({ message: 'Open to all origins!' });
});
// เริ่มต้น server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
และนี่ก็เป็น CORS กลไกที่คอยอนุญาตการเรียกข้อมูลที่อยู่ต่างโดเมนกันนั่นเอง แอดหวังว่าบทความนี้จะช่วยให้เข้าใจ CORS ใน Node.js ได้ง่ายขึ้นนะงับ