วิธีการแก้ CORS Error

CORS ย่อมาจาก Cross-Origin Resource Sharing เป็นกลไกที่ใช้ HTTP headers เพื่อให้ Server สามารถอนุญาตหรือไม่อนุญาตการร้องขอการเข้าถึงทรัพยากรใดๆ จากเว็บไซต์หรือ Origin อื่นๆ ที่ไม่ใช่การร้องขอจาก Origin ของตัวเองได้

ซึ่ง Origin มีด้วยกันทั้งหมด 3 ส่วน ประกอบไปด้วย Schema, Host และ Port

origin request header
Origin: The Origin request header indicates the origin

หากส่วนใดส่วนหนึ่งของ Origin แตกต่างกัน จะถือว่าเป็นคนละ Origin กัน เมื่อมีการร้องขอการเข้าถึงทรัพยากรจาก Origin ที่ต่างกัน จะเกิดกลไกของ CORS ขึ้น แต่หากเป็นการร้องขอของ Origin ที่เหมือนกัน จะไม่เกิด CORS ขึ้น

สิ่งที่เกิดขึ้นเมื่อมีการร้องขอการเข้าถึงทรัพยากรข้าม Origin คือ เบราว์เซอร์จะส่ง HTTP headers ที่มี Origin header ไปถามฝั่ง Server ก่อนว่าจะอนุญาตให้ Origin ต้นทางสามารถเข้าถึงทรัพยากรได้หรือไม่ ถ้า Server ตอบกลับมาว่าอนุญาต Origin ต้นทางก็จะสามารถเข้าถึงทรัพยากรได้ โดยเบราว์เซอร์จะจำคำตอบอนุญาตไว้ 3600 วินาที เพื่อที่จะได้ไม่ต้องถาม Server ซ้ำอีก

แต่ถ้า Server ตอบกลับว่าไม่อนุญาตให้เข้าถึงทรัพยากรจะเกิด CORS error ขึ้น

CORS error: No ‘Access-Control-Allow-Origin’ header

การส่ง HTTP headers เป็นการส่งของเบราว์เซอร์ หากเบราว์เซอร์ไม่มี Support CORS การร้องขอทรัพยากรก็จะสามารถเข้าถึงได้เลย (Browser ที่ Support CORS) หรือการร้องขอที่เกิดจาก Server ร้องขอ Server ก็จะไม่มี CORS เกิดขึ้น

วิธีแก้เมื่อเกิดข้อผิดพลาด CORS ขึ้นในกรณีที่เป็นการยิง API หรือร้องขอไปยัง Server ที่เราไม่ได้เขียนขึ้นมาเอง คือ ให้เราเขียน Server เพื่อเป็นตัวแทนในการร้องขอไปยัง Server โดยตรง แล้วให้ Client เรียกใช้ทรัพยากรที่ได้จาก Server ที่เขียนขึ้นมาอีกที

วิธีแก้เมื่อเกิดข้อผิดพลาด CORS ขึ้นในกรณีที่ Server เป็น Server ที่เราเขียนขึ้นมาเอง (กรณีแยกส่วน Front-end และ Back-end) คือ ที่ฝั่ง Server ให้เขียนระบุโดเมนที่ต้องการอนุญาตให้เข้าถึงทรัพยากรได้ โดยกำหนด Access-Control-Allow-Origin

ถ้าเขียน Server เป็น PHP และต้องการอนุญาตให้โดเมนทั้งหมดเข้าถึงทรัพยากรได้

header('Access-Control-Allow-Origin: *');

แต่ถ้าต้องการอนุญาตแค่เฉพาะโดเมนที่จะให้เข้าถึงทรัพยากร สามารถเขียนระบุโดเมนได้เลย

header('Access-Control-Allow-Origin: https://www.example.com');

และสามารถกำหนด Methods, Headers และระยะเวลาที่จะให้เบราว์เซอร์จำคำตอบ

header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: X-PINGOTHER, Content-Type');
header('Access-Control-Max-Age: 86400');

ถ้าเขียน Server เป็น NodeJS ให้ระบุไว้ที่ไฟล์ .js ได้เลย

const express = require("express")
const app = express()
const PORT = process.env.PORT || 8080

app.use((req, res, next) => {
      res.header('Access-Control-Allow-Origin', '*') // สามารถระบุโดเมนได้
      res.header('Access-Control-Allow-Methods','POST, GET, PUT, PATCH, DELETE, OPTIONS')
      res.header('Access-Control-Allow-Headers','Content-Type, Option, Authorization')
      return next()
   })
}

app.use('/', (req,res) => res.send("Hello World!"))
app.listen(PORT, () => { console.info(`server started on port ${PORT}`)})

หากต้องการอนุญาตมากกว่า 1 โดเมน

const express = require("express")
const app = express()
const PORT = process.env.PORT || 8080

app.use((req, res, next) => {
   let ALLOW_ORIGIN = ['example-a.com', 'example-b.com', 'example-c.com']
   let ORIGIN = req.headers.origin
      if (ALLOW_ORIGIN.includes(ORIGIN)) {
        res.header('Access-Control-Allow-Origin', ORIGIN)
      }
      res.header('Access-Control-Allow-Methods','POST, GET, PUT, PATCH, DELETE, OPTIONS')
      res.header('Access-Control-Allow-Headers','Content-Type, Option, Authorization')
      return next()
   })
}

app.use('/', (req,res) => res.send("Hello World!"))
app.listen(PORT, () => { console.info(`server started on port ${PORT}`)})

สรุป

การเกิดข้อผิดพลาด CORS เกิดจากการปฏิเสธการร้องขอการเข้าถึงทรัพยากรของ Server ซึ่งวิธีการแก้ไขข้อผิดพลาดจากการร้องขอการเข้าถึงทรัพยากรข้าม Origin ในกรณีที่ไม่ได้เขียน Server เอง ต้องสร้าง Server เพื่อเป็นตัวแทน Client ในการร้องขอ Server ขึ้นมา และในกรณีที่เขียน Server เอง ให้เขียนกำหนดโดเมนที่ต้องการอนุญาตให้เข้าถึงทรัพยากรได้ หวังว่าบทความนี้จะเป็นประโยชน์กับคนที่พบเจอข้อผิดพลาดนี้ รวมถึงคนที่ต้องการทำความเข้าใจเรื่อง CORS มากขึ้นด้วย

Was this article helpful?