คุณเปิดตัวส่วนหน้า (frontend) ใหม่, เปิดคอนโซล, แล้วก็เจอ: ข้อผิดพลาด CORS สีแดงที่แจ้งว่าคำขอถูก “บล็อกโดยนโยบาย CORS” API ของคุณทำงานได้ดีใน Apidog หรือ curl แต่เบราว์เซอร์ปฏิเสธที่จะส่งการตอบกลับให้ JavaScript ของคุณ น่าหงุดหงิดไหม? ใช่. ลึกลับไหม? ไม่เลยเมื่อคุณรู้ว่าข้อผิดพลาดอยู่ตรงไหน
นี่คือข้อเท็จจริงสำคัญที่บทช่วยสอนส่วนใหญ่ไม่ค่อยกล่าวถึง: ข้อผิดพลาด CORS ถูกบังคับใช้โดยเบราว์เซอร์ แต่มีสาเหตุมาจากเซิร์ฟเวอร์ เบราว์เซอร์บล็อกการตอบกลับเพราะเซิร์ฟเวอร์ของคุณไม่ได้ส่งเฮดเดอร์ Access-Control-Allow-Origin ที่ถูกต้อง ดังนั้นการแก้ไขเกือบทั้งหมดจึงเกิดขึ้นในการตั้งค่าคอนฟิกของเซิร์ฟเวอร์ ไม่ใช่ในโค้ดส่วนหน้าของคุณ
คู่มือนี้จะอธิบายว่า CORS ทำงานอย่างไร, คำขอ preflight ทำงานอย่างไร, ข้อความข้อผิดพลาด CORS ที่พบบ่อยที่สุดหกข้อพร้อมวิธีแก้ไขที่ถูกต้องสำหรับแต่ละข้อ, และการตั้งค่าคอนฟิกที่ใช้งานได้สำหรับ Express, Spring Boot และ Nginx นอกจากนี้ คุณยังจะได้เรียนรู้วิธีดีบักจากภายนอกเบราว์เซอร์ ซึ่งเป็นวิธีที่เร็วที่สุดในการแยกแยะระหว่าง “การตั้งค่าเซิร์ฟเวอร์ไม่ถูกต้อง” กับ “เบราว์เซอร์บล็อก”
ข้อผิดพลาด CORS คืออะไร (และไม่ใช่อะไร)
CORS ย่อมาจาก Cross-Origin Resource Sharing โดยค่าเริ่มต้น เบราว์เซอร์จะบังคับใช้นโยบาย same-origin: JavaScript ที่ทำงานอยู่บน https://app.example.com ไม่สามารถอ่านการตอบกลับจาก https://api.example.com ได้ เนื่องจาก scheme, host หรือ port แตกต่างกัน CORS คือกลไกที่เซิร์ฟเวอร์ใช้เพื่อผ่อนคลายกฎนี้โดยเจตนา รายละเอียดทั้งหมดอยู่ใน เอกสาร MDN CORS และอัลกอริทึมพื้นฐานถูกกำหนดไว้ใน Fetch specification
สามประเด็นต่อไปนี้จะช่วยขจัดความสับสนส่วนใหญ่:
- เบราว์เซอร์เป็นผู้บังคับใช้ มีเพียงเบราว์เซอร์เท่านั้นที่ใช้การตรวจสอบ CORS การเรียกจากเซิร์ฟเวอร์ถึงเซิร์ฟเวอร์, curl, และไคลเอนต์ API บนเดสก์ท็อป จะละเลยมันโดยสิ้นเชิง
- เซิร์ฟเวอร์เป็นผู้ตั้งค่าคอนฟิก เบราว์เซอร์ตัดสินใจจากเฮดเดอร์การตอบกลับที่เซิร์ฟเวอร์ของคุณส่งไป ไม่มีเฮดเดอร์ ก็ไม่มีการเข้าถึง
- คำขอมักจะยังคงไปถึงเซิร์ฟเวอร์ สำหรับคำขอแบบง่ายๆ เซิร์ฟเวอร์จะประมวลผลทุกอย่างและตอบกลับ จากนั้นเบราว์เซอร์จะระงับการตอบกลับจาก JavaScript ของคุณ CORS ไม่ใช่กำแพงรักษาความปลอดภัยรอบ API ของคุณ แต่จะปกป้องผู้ใช้จากหน้าเว็บที่เป็นอันตรายที่อ่านข้อมูลข้ามต้นทางด้วยคุกกี้ของพวกเขา
ดังนั้นเมื่อคุณเห็นข้อผิดพลาด CORS อย่าพยายามหาทางแก้ไขที่ส่วนหน้า ให้อ่านข้อความแสดงข้อผิดพลาด จากนั้นแก้ไขเฮดเดอร์ที่ขาดหายไปหรือไม่ถูกต้องบนเซิร์ฟเวอร์
โครงสร้างของคำขอ preflight
ก่อนคำขอข้ามต้นทางบางอย่าง เบราว์เซอร์จะส่งตัวสำรวจ: คำขอ OPTIONS ที่เรียกว่า preflight มันจะทำงานเมื่อคำขอของคุณใช้วิธีการนอกเหนือจาก GET, HEAD หรือ POST, ส่งเฮดเดอร์แบบกำหนดเอง เช่น Authorization หรือใช้ Content-Type เช่น application/json
คำขอ preflight มีลักษณะดังนี้:
OPTIONS /v1/orders HTTP/1.1
Host: api.example.com
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization, content-type
เบราว์เซอร์กำลังถามว่า: “หน้าเว็บที่ app.example.com ต้องการ POST ที่นี่พร้อมเฮดเดอร์เหล่านี้ อนุญาตหรือไม่?” คำตอบที่ถูกต้องจากเซิร์ฟเวอร์:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Max-Age: 86400
Vary: Origin
หากส่วนใดส่วนหนึ่งขาดหายไป เบราว์เซอร์จะยกเลิกคำขอจริงก่อนที่จะทำงาน ปลายทาง API ของคุณจะไม่ทำงาน, บันทึกของคุณจะแสดงเพียงแค่การเข้าถึง OPTIONS เท่านั้น, และคอนโซลจะแสดงข้อผิดพลาด CORS Access-Control-Max-Age จะบอกให้เบราว์เซอร์แคชคำตัดสินนี้ (86400 วินาทีในที่นี้) ดังนั้นคำขอที่ซ้ำกันจะข้ามการตรวจสอบ preflight
โปรดจำขั้นตอนสองขั้นตอนนี้ไว้ การดีบัก CORS ส่วนใหญ่จะสรุปได้ด้วยคำถามเดียว: คำขอ preflight ล้มเหลว หรือคำขอจริงล้มเหลว?
ข้อผิดพลาด CORS ที่พบบ่อยที่สุด 6 ประการ และวิธีแก้ไขแต่ละข้อ
เบราว์เซอร์เขียนข้อความแสดงข้อผิดพลาด CORS ได้แม่นยำอย่างน่าประหลาดใจ จับคู่ข้อความของคุณกับรายการด้านล่าง
1. ไม่มีเฮดเดอร์ ‘Access-Control-Allow-Origin’
คลาสสิกมาก เซิร์ฟเวอร์ของคุณส่งการตอบกลับที่ไม่มีเฮดเดอร์ CORS เลย เบราว์เซอร์ไม่มีอะไรจะประเมิน จึงบล็อกการเข้าถึง
วิธีแก้ไข: กำหนดค่าเซิร์ฟเวอร์ให้ส่ง Access-Control-Allow-Origin โดยระบุ origin ที่ร้องขออย่างเฉพาะเจาะจง หรือใช้ * สำหรับ API สาธารณะที่ไม่มีการตรวจสอบสิทธิ์:
Access-Control-Allow-Origin: https://app.example.com
ข้อผิดพลาดที่พบบ่อย: การตอบกลับข้อผิดพลาดมักจะไม่มีเฮดเดอร์ CORS แม้ว่าการตอบกลับที่สำเร็จจะมีก็ตาม หาก API ของคุณส่งคืน 500 และมิดเดิลแวร์ของคุณจัดการเฉพาะ 200s คอนโซลจะแสดงข้อผิดพลาด CORS แทนที่จะเป็นข้อผิดพลาดของเซิร์ฟเวอร์ที่แท้จริง ตรวจสอบให้แน่ใจว่าเฮดเดอร์ CORS ถูกแนบไปกับการตอบกลับทุกครั้ง รวมถึงหน้า 403 Forbidden และ 500 ด้วย
2. ไม่สามารถใช้ Wildcard ‘*’ กับข้อมูลรับรองได้
ข้อความแจ้งว่า: “ค่าของเฮดเดอร์ ‘Access-Control-Allow-Origin’ ต้องไม่ใช่ wildcard ‘*’ เมื่อโหมดข้อมูลรับรองของคำขอคือ ‘include’”
ส่วนหน้าของคุณส่งคุกกี้หรือเฮดเดอร์การตรวจสอบสิทธิ์พร้อม credentials: 'include' แต่เซิร์ฟเวอร์ตอบกลับด้วย Access-Control-Allow-Origin: * ข้อกำหนด Fetch ห้ามการจับคู่แบบนี้ การใช้ wildcard ร่วมกับข้อมูลรับรองจะทำให้เว็บไซต์ใดๆ บนอินเทอร์เน็ตสามารถอ่านการตอบกลับที่ผ่านการตรวจสอบสิทธิ์ได้
วิธีแก้ไข: สะท้อน origin ที่ถูกต้องแทนการใช้ wildcard และเพิ่มเฮดเดอร์ข้อมูลรับรอง:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
ตรวจสอบ Origin ที่เข้ามากับรายการที่อนุญาต (allowlist) ก่อนที่จะสะท้อนกลับ การสะท้อน origin ที่ไม่ระบุเจาะจงพร้อมกับการเปิดใช้งานข้อมูลรับรองจะทำให้การป้องกันทั้งหมดไร้ผล
3. การตอบกลับคำขอ preflight ไม่ผ่านการตรวจสอบการควบคุมการเข้าถึง
เซิร์ฟเวอร์ของคุณไม่เคยจัดการคำขอ OPTIONS เลย บางทีเส้นทางอาจกำหนดไว้สำหรับ POST เท่านั้น ดังนั้น OPTIONS จึงคืนค่า 404 หรือ 405 บางทีมิดเดิลแวร์การตรวจสอบสิทธิ์อาจปฏิเสธด้วย 401 เนื่องจาก preflight ไม่ได้ส่งโทเค็น (เบราว์เซอร์ไม่เคยแนบข้อมูลรับรองไปกับ preflights)
วิธีแก้ไข: จัดการ OPTIONS อย่างชัดเจนและคืนค่า 2xx พร้อมชุดเฮดเดอร์ CORS เต็มรูปแบบก่อนการตรวจสอบสิทธิ์จะทำงาน ในเฟรมเวิร์กส่วนใหญ่ การติดตั้งมิดเดิลแวร์ CORS ก่อนจะช่วยแก้ปัญหานี้ได้ หากคุณกำลังเขียนด้วยตนเอง:
app.options('/v1/orders', (req, res) => {
res.set({
'Access-Control-Allow-Origin': 'https://app.example.com',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Authorization, Content-Type'
});
res.sendStatus(204);
});
4. ค่าเฮดเดอร์ไม่เท่ากับ origin ที่ให้มา
เซิร์ฟเวอร์ส่งเฮดเดอร์ Access-Control-Allow-Origin แต่ระบุ origin ที่ผิด สาเหตุที่พบบ่อย: origin ของ production ที่ถูกฮาร์ดโค้ดไว้ในขณะที่คุณกำลังทดสอบจาก http://localhost:5173, การเปรียบเทียบ allowlist ล้มเหลวระหว่าง http กับ https, หรือมีเครื่องหมายทับท้าย (https://app.example.com/ ไม่ใช่ค่า origin ที่ถูกต้อง)
วิธีแก้ไข: เปรียบเทียบเฮดเดอร์ Origin ของคำขอกับ allowlist ของคุณอย่างแม่นยำ, สะท้อนสิ่งที่ตรงกัน, และส่ง Vary: Origin เพื่อให้แคชและ CDN ไม่เสิร์ฟเฮดเดอร์ของ origin หนึ่งให้กับอีก origin หนึ่ง:
const allowed = ['https://app.example.com', 'http://localhost:5173'];
if (allowed.includes(req.headers.origin)) {
res.set('Access-Control-Allow-Origin', req.headers.origin);
res.set('Vary', 'Origin');
}
5. ฟิลด์เฮดเดอร์คำขอหรือเมธอดไม่ได้รับอนุญาต
ข้อความที่คล้ายกันสองข้อความ: “ฟิลด์เฮดเดอร์คำขอ authorization ไม่ได้รับอนุญาตโดย Access-Control-Allow-Headers ในการตอบกลับ preflight” และ “เมธอด PUT ไม่ได้รับอนุญาตโดย Access-Control-Allow-Methods”
คำขอ preflight สำเร็จ แต่คำตอบไม่ได้ครอบคลุมสิ่งที่คำขอของคุณต้องการ คุณเพิ่มเฮดเดอร์ Authorization หรือ X-Request-Id และ allowlist ของเซิร์ฟเวอร์ไม่เคยกล่าวถึงสิ่งเหล่านั้น
วิธีแก้ไข: ขยายการตอบกลับ preflight เพื่อรวมเฮดเดอร์และเมธอดทั้งหมดที่ส่วนหน้าของคุณส่ง:
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type, X-Request-Id
ชื่อเฮดเดอร์ในที่นี้ไม่คำนึงถึงตัวพิมพ์เล็กใหญ่ เมธอดคำนึงถึงตัวพิมพ์เล็กใหญ่และเป็นตัวพิมพ์ใหญ่ทั้งหมด
6. ไม่อนุญาตให้มีการเปลี่ยนเส้นทางสำหรับคำขอ preflight
คำขอ preflight ไปยัง URL ที่คืนค่า 301 หรือ 302 และเบราว์เซอร์ปฏิเสธที่จะติดตามการเปลี่ยนเส้นทางระหว่าง preflight สาเหตุทั่วไป: URL http ที่เปลี่ยนเส้นทางไปยัง https, เครื่องหมายทับท้ายที่ขาดหายไปซึ่งเฟรมเวิร์กของคุณ “ช่วย” เปลี่ยนเส้นทางให้, หรือเกตเวย์ที่ส่ง /v1/orders ไปยัง /v1/orders/
วิธีแก้ไข: ชี้ส่วนหน้าของคุณไปยัง URL สุดท้ายโดยตรง ใช้ https ตั้งแต่เริ่มต้น, จับคู่รูปแบบเครื่องหมายทับท้ายของเราเตอร์ของคุณ, และยืนยันด้วยการเรียก OPTIONS ด้วยตนเองเพื่อตรวจสอบว่าปลายทางตอบกลับด้วย 2xx แทนที่จะเป็น 3xx
ตัวอย่างการตั้งค่าคอนฟิกเซิร์ฟเวอร์
นี่คือการตั้งค่า CORS ที่ถูกต้องในสามสแต็กทั่วไป
Express
ใช้ มิดเดิลแวร์ cors อย่างเป็นทางการ แทนที่จะเขียนเฮดเดอร์ด้วยตนเอง:
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: ['https://app.example.com', 'http://localhost:5173'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
allowedHeaders: ['Authorization', 'Content-Type'],
credentials: true,
maxAge: 86400
}));
ติดตั้งก่อนมิดเดิลแวร์การตรวจสอบสิทธิ์ของคุณ เพื่อไม่ให้ preflights ถูกปฏิเสธเนื่องจากโทเค็นหายไป นักพัฒนา Python จะได้รับรูปแบบเดียวกันจาก ส่วนขยาย Flask-CORS ซึ่งห่อหุ้มตรรกะเฮดเดอร์ที่เหมือนกันสำหรับแอปพลิเคชัน Flask
Spring Boot
การตั้งค่าคอนฟิกทั่วโลกผ่าน WebMvcConfigurer:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/v1/**")
.allowedOrigins("https://app.example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("Authorization", "Content-Type")
.allowCredentials(true)
.maxAge(86400);
}
}
ใช้ Spring Security อยู่ใช่ไหม? เรียกใช้ .cors(Customizer.withDefaults()) ใน security filter chain ของคุณด้วย มิฉะนั้นเลเยอร์ความปลอดภัยจะบล็อก preflights ก่อนที่การตั้งค่าคอนฟิก MVC จะเห็นมัน ดู เอกสาร Spring CORS สำหรับชุดตัวเลือกทั้งหมด
Nginx
เมื่อ Nginx จัดการคำขออยู่หน้าแอปของคุณ ให้ตอบกลับ preflights ที่ขอบ (edge):
location /v1/ {
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin "https://app.example.com" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Authorization, Content-Type" always;
add_header Access-Control-Max-Age 86400 always;
return 204;
}
add_header Access-Control-Allow-Origin "https://app.example.com" always;
add_header Vary "Origin" always;
proxy_pass http://backend;
}
แฟล็ก always มีความสำคัญ หากไม่มี Nginx จะละทิ้งคำสั่ง add_header ในการตอบกลับ 4xx และ 5xx ซึ่งจะสร้างข้อผิดพลาดหมายเลขหนึ่งขึ้นมาใหม่ในทุกคำขอที่ล้มเหลว และเลือกเลเยอร์เดียวที่จะจัดการ CORS: หากทั้ง Nginx และแอปของคุณเพิ่มเฮดเดอร์ เบราว์เซอร์จะเห็นข้อมูลซ้ำซ้อน เช่น Access-Control-Allow-Origin: *, * และปฏิเสธการตอบกลับ
ดีบัก CORS นอกเบราว์เซอร์ด้วย Apidog
ข้อผิดพลาดในคอนโซลจะบอกคุณว่าเบราว์เซอร์บล็อกบางอย่าง มันไม่ได้บอกคุณว่าเซิร์ฟเวอร์ส่งอะไร วิธีที่เร็วที่สุดในการดูความจริงคือการนำเบราว์เซอร์ออกจากกระบวนการ
Apidog เป็นไคลเอนต์ API บนเดสก์ท็อป ดังนั้นคำขอของมันจึงไม่ถูกตรวจสอบ CORS โดยเบราว์เซอร์เลย นั่นทำให้คุณสามารถทดลองได้อย่างชัดเจน: ส่งคำขอเดียวกันจาก Apidog ที่ส่วนหน้าของคุณกำลังทำอยู่ หากสำเร็จ แสดงว่าตรรกะ API ของคุณใช้งานได้ดี และปัญหาเกิดจากเฮดเดอร์ CORS ที่ขาดหายไปเท่านั้น หากล้มเหลวด้วย คุณมีบั๊ก API ทั่วไปที่มาในชุด CORS และ เทคนิคการทดสอบ API ทั่วไปสามารถนำมาใช้ได้
เซสชันการดีบัก CORS ใน Apidog มีลักษณะดังนี้:
- จำลองคำขอจริง คัดลอกคำขอที่ล้มเหลวจากแท็บ Network ของเบราว์เซอร์ของคุณ และสร้างใหม่ใน Apidog ด้วยเมธอด, เฮดเดอร์, และบอดี้เดียวกัน ตรวจสอบสถานะและบอดี้ หากได้ 500 ในขั้นตอนนี้ แสดงว่า CORS ไม่ใช่ปัญหาของคุณเลย
- ทดสอบ preflight ด้วยตนเอง สร้างคำขอใหม่, ตั้งค่าเมธอดเป็น
OPTIONS, และเพิ่มเฮดเดอร์ที่เบราว์เซอร์จะส่ง:Origin: https://app.example.com,Access-Control-Request-Method: POST, และAccess-Control-Request-Headers: authorization, content-typeแล้วส่งไป - ตรวจสอบเฮดเดอร์การตอบกลับ ในส่วนการตอบกลับ ให้มองหา
Access-Control-Allow-Origin,Access-Control-Allow-Methods, และAccess-Control-Allow-Headersเปรียบเทียบแต่ละค่ากับสิ่งที่ส่วนหน้าของคุณต้องการ เฮดเดอร์ที่ขาดหายไป, origin ที่ผิด, หรือสถานะ 3xx จะปรากฏขึ้นทันที โดยไม่ต้องเดาในคอนโซล - ยืนยันการแก้ไข หลังจากเปลี่ยนการตั้งค่าคอนฟิกเซิร์ฟเวอร์ ให้ส่งคำขอ
OPTIONSที่บันทึกไว้ซ้ำ และดูการอัปเดตของเฮดเดอร์ ไม่ต้องปรับใช้ส่วนหน้าใหม่, ไม่ต้องล้างแคช
ขั้นตอนการทำงานนี้ยังช่วยยุติข้อถกเถียงอันยาวนานที่ว่า “ทำงานในไคลเอนต์ API ของฉัน แต่ล้มเหลวในเบราว์เซอร์” ได้ภายในไม่กี่วินาที ซึ่งเป็นปริศนาเดียวกับเบื้องหลังคำถาม การทดสอบ Postman CORS ไคลเอนต์ทำงานได้เพราะมันข้าม CORS เบราว์เซอร์ล้มเหลวเพราะเซิร์ฟเวอร์ของคุณไม่ได้กล่าวคำวิเศษณ์ ดาวน์โหลด Apidog ฟรีและบันทึกคำขอ OPTIONS ไว้ข้างการทดสอบปลายทางปกติของคุณ; ปัญหา CORS ในอนาคตจะถูกแก้ไขได้ในคลิกเดียว
รายการตรวจสอบ CORS ใน 30 วินาที
ก่อนที่คุณจะรายงานบั๊ก ให้ตรวจสอบรายการนี้:
- การตอบกลับที่ล้มเหลวนั้นมี
Access-Control-Allow-Originอยู่เลยหรือไม่? - ค่าของมันตรงกับ origin ของหน้าเว็บของคุณอย่างแม่นยำหรือไม่ (scheme, host, port, ไม่มีเครื่องหมายทับท้าย)?
- ใช้คุกกี้หรือการตรวจสอบสิทธิ์ใช่หรือไม่? ยืนยัน origin ที่เจาะจงพร้อมกับ
Access-Control-Allow-Credentials: trueห้ามใช้*โดยเด็ดขาด OPTIONSคืนค่า 2xx พร้อมเมธอดและเฮดเดอร์ที่ครอบคลุมคำขอของคุณหรือไม่?- มีการเปลี่ยนเส้นทางบน URL ของ preflight หรือไม่?
- การตอบกลับข้อผิดพลาด (401, 403, 500) มีเฮดเดอร์ CORS เหมือนกับการตอบกลับที่สำเร็จหรือไม่?
เก้าในสิบครั้ง หนึ่งในหกข้อนี้คือคำตอบของคุณ ตรวจสอบด้วยคำขอ OPTIONS ด้วยตนเองใน Apidog, แก้ไขการตั้งค่าคอนฟิกเซิร์ฟเวอร์, แล้วกลับไปทำงานต่อได้เลย
คำถามที่พบบ่อย
ทำไมฉันถึงได้รับข้อผิดพลาด CORS เฉพาะในเบราว์เซอร์เท่านั้น?
เพราะมีเพียงเบราว์เซอร์เท่านั้นที่บังคับใช้ CORS นโยบาย same-origin ช่วยปกป้องผู้ใช้จากหน้าเว็บที่เป็นอันตรายที่อ่านข้อมูลที่ได้รับการตรวจสอบสิทธิ์ของพวกเขา ดังนั้นเบราว์เซอร์จะตรวจสอบ Access-Control-Allow-Origin ในการตอบกลับข้าม origin ทุกครั้ง curl, บริการแบ็คเอนด์, และไคลเอนต์เดสก์ท็อปไม่มีกฎดังกล่าว หากคำขอสำเร็จในทุกที่ยกเว้นในเบราว์เซอร์ แสดงว่าเซิร์ฟเวอร์ของคุณขาดหรือตั้งค่าคอนฟิกเฮดเดอร์ CORS ไม่ถูกต้อง; ตัว API เองนั้นทำงานได้ปกติ
CORS ใช้กับ Postman หรือ Apidog หรือไม่?
ไม่ Postman และ Apidog เป็นแอปพลิเคชันเดสก์ท็อป ไม่ใช่หน้าเว็บที่ทำงานอยู่ภายในแซนด์บ็อกซ์ของเบราว์เซอร์ ดังนั้นคำขอของพวกเขาจึงข้าม CORS ไปโดยสิ้นเชิง นั่นคือสิ่งที่ทำให้พวกมันมีประโยชน์สำหรับการดีบัก CORS: พวกมันแสดงเฮดเดอร์การตอบกลับดิบของเซิร์ฟเวอร์โดยไม่มีการกรองของเบราว์เซอร์ ความสับสนจาก การทดสอบ Postman CORS มักจะเริ่มต้นที่นี่; คำขอที่ผ่านในไคลเอนต์เดสก์ท็อปไม่ได้พิสูจน์อะไรเกี่ยวกับพฤติกรรมของเบราว์เซอร์ แต่เป็นการแยกแยะเลเยอร์ที่ล้มเหลวได้
ข้อผิดพลาด CORS เป็นคุณสมบัติความปลอดภัยหรือบั๊ก?
เป็นคุณสมบัติ ข้อผิดพลาด CORS หมายความว่าเบราว์เซอร์กำลังทำหน้าที่ของมัน: ปฏิเสธที่จะเปิดเผยข้อมูลการตอบกลับข้าม origin ไปยังสคริปต์เว้นแต่เซิร์ฟเวอร์จะอนุญาต การปิดใช้งาน CORS ในเบราว์เซอร์ด้วยแฟล็กหรือส่วนขยายจะซ่อนอาการบนเครื่องของคุณในขณะที่ผู้ใช้ทุกคนยังคงประสบปัญหาเดิม แก้ไขเฮดเดอร์เซิร์ฟเวอร์แทน
ฉันสามารถใช้ Access-Control-Allow-Origin: * ได้ทุกที่หรือไม่?
ใช้ได้เฉพาะกับ API สาธารณะแบบอ่านอย่างเดียวที่ไม่มีคุกกี้หรือการตรวจสอบสิทธิ์ Wildcard จะถูกปฏิเสธเมื่อมีการรวมข้อมูลรับรอง และมันเป็นการประกาศว่าข้อมูลของคุณเปิดเผยต่อทุก origin บนเว็บ สำหรับการตรวจสอบสิทธิ์ใดๆ ให้รักษา allowlist ของ origin, สะท้อน origin ที่ตรงกัน, และส่ง Vary: Origin เพื่อให้แคชที่ใช้ร่วมกันแยกระหว่างการตอบกลับ
