XMLHttpRequest ไม่สามารถโหลดส่วนหัว XXX No 'Access-Control-Allow-Origin'


114

tl; dr; เกี่ยวกับนโยบายแหล่งกำเนิดเดียวกัน

ฉันมีกระบวนการ Grunt ซึ่งเริ่มต้นอินสแตนซ์ของเซิร์ฟเวอร์ express.js สิ่งนี้ใช้งานได้ดีจนถึงตอนนี้เมื่อเริ่มแสดงหน้าว่างโดยมีสิ่งต่อไปนี้ปรากฏในบันทึกข้อผิดพลาดในคอนโซลของนักพัฒนาซอฟต์แวร์ใน Chrome (เวอร์ชันล่าสุด):

XMLHttpRequest ไม่สามารถโหลดhttps://www.example.com/ ไม่มีส่วนหัว 'Access-Control-Allow-Origin' อยู่ในทรัพยากรที่ร้องขอ Origin ' http: // localhost: 4300 ' จึงไม่ได้รับอนุญาตให้เข้าถึง

อะไรทำให้ฉันไม่สามารถเข้าถึงเพจได้


ฉันกำลังทำงานบนเว็บไซต์และมันก็เรียบร้อยดีเมื่อห้านาทีที่แล้ว
Peter David Carter

1
มันออกส่วนหัว CORS หรือไม่ บางทีถ้าคุณแชร์รหัสมันจะง่ายกว่าที่จะเห็น
Jaromanda X

อย่างมีเหตุผล ฉันควรถามแผนกใด ฉันแค่ทำกระดูกสันหลังส่วนใหญ่หุ่นจำลอง ...
ปีเตอร์เดวิดคาร์เตอร์

ใช่. ฉันคิดว่าองค์กรของแผนกต่างๆไม่เหมือนกันเสมอไปดังนั้นจึงอาจเป็นคำถามที่คลุมเครือ แต่ฉันต้องการทราบข้อมูลเกี่ยวกับแบ็กเอนด์ / การกำหนดเส้นทาง / sys-admin ใน บริษัท ของฉันและนี่เป็นข้ออ้างที่ดีในการทำความคุ้นเคย ตัวเองดังนั้นหากมีปัญหาในอนาคตฉันสามารถช่วยได้
Peter David Carter

ฉันจะถามใครบางคนในฝั่งเซิร์ฟเวอร์ในการดำเนินการของคุณ พวกเขาจะต้องเปลี่ยนให้คุณหากคุณสามารถเข้าถึงได้ก่อนหน้านี้
Larry Lane

คำตอบ:


210

tl; dr - มีบทสรุปในตอนท้ายและส่วนหัวในคำตอบเพื่อให้ง่ายต่อการค้นหาส่วนที่เกี่ยวข้อง ขอแนะนำให้อ่านทุกอย่างแม้ว่าจะมีพื้นฐานที่เป็นประโยชน์ในการทำความเข้าใจว่าเหตุใดจึงทำให้เห็นว่าการนำไปใช้ในสถานการณ์ต่างๆง่ายขึ้นอย่างไร

เกี่ยวกับนโยบายแหล่งกำเนิดเดียวกัน

นี่คือเดียวกันนโยบายแหล่งกำเนิดสินค้า เป็นคุณลักษณะด้านความปลอดภัยที่ใช้งานโดยเบราว์เซอร์

กรณีเฉพาะของคุณกำลังแสดงวิธีการใช้งาน XMLHttpRequest (และคุณจะได้รับผลลัพธ์ที่เหมือนกันหากคุณใช้การดึงข้อมูล) แต่ยังใช้กับสิ่งอื่น ๆ ด้วย (เช่นรูปภาพที่โหลดลงใน a <canvas>หรือเอกสารที่โหลดลงใน a <iframe>) ด้วย การใช้งานที่แตกต่างกันเล็กน้อย

(น่าแปลกที่ยังใช้กับแบบอักษร CSS ด้วย แต่นั่นเป็นเพราะผู้ก่อตั้งที่พบยืนยันใน DRM และไม่ใช่สำหรับปัญหาด้านความปลอดภัยที่โดยทั่วไปนโยบาย Origin Origin จะครอบคลุม)

สถานการณ์มาตรฐานที่แสดงให้เห็นถึงความต้องการ SOP สามารถแสดงได้ด้วยอักขระสามตัว :

  • อลิซเป็นคนที่มีเว็บเบราว์เซอร์
  • Bob ทำงานเว็บไซต์ ( https://www.[website].com/ในตัวอย่างของคุณ)
  • Mallory ทำงานเว็บไซต์ ( http://localhost:4300ในตัวอย่างของคุณ)

อลิซลงชื่อเข้าใช้ไซต์ของ Bob และมีข้อมูลที่เป็นความลับอยู่ที่นั่น บางทีอาจเป็นอินทราเน็ตของ บริษัท (เข้าถึงได้เฉพาะเบราว์เซอร์บน LAN) หรือธนาคารออนไลน์ของเธอ (เข้าถึงได้ด้วยคุกกี้ที่คุณได้รับหลังจากป้อนชื่อผู้ใช้และรหัสผ่านเท่านั้น)

Alice เข้าชมเว็บไซต์ของ Mallory ซึ่งมี JavaScript บางส่วนที่ทำให้เบราว์เซอร์ของ Alice ส่งคำขอ HTTP ไปยังเว็บไซต์ของ Bob (จากที่อยู่ IP ของเธอพร้อมคุกกี้ของเธอเป็นต้น) ซึ่งอาจทำได้ง่ายเพียงแค่ใช้XMLHttpRequestและอ่านไฟล์responseText.

นโยบายแหล่งกำเนิดเดียวกันของเบราว์เซอร์ป้องกันไม่ให้ JavaScript อ่านข้อมูลที่ส่งคืนโดยเว็บไซต์ของ Bob (ซึ่ง Bob และ Alice ไม่ต้องการให้ Mallory เข้าถึง) (โปรดทราบว่าคุณสามารถแสดงภาพโดยใช้<img>องค์ประกอบข้ามจุดเริ่มต้นได้เนื่องจากเนื้อหาของภาพไม่เปิดเผยต่อ JavaScript (หรือ Mallory) ... เว้นแต่คุณจะโยนผ้าใบลงในส่วนผสมซึ่งในกรณีนี้คุณจะสร้างแหล่งที่มาเดียวกัน ข้อผิดพลาดในการละเมิด)


เหตุใดจึงใช้นโยบายแหล่งกำเนิดเดียวกันเมื่อคุณไม่คิดว่าควร

สำหรับ URL ที่ระบุอาจเป็นไปได้ว่าไม่จำเป็นต้องใช้ SOP สถานการณ์ทั่วไปสองสามกรณีที่เป็นกรณีนี้:

  • Alice, Bob และ Mallory เป็นคน ๆ เดียวกัน
  • Bob กำลังให้ข้อมูลสาธารณะทั้งหมด

… แต่เบราว์เซอร์ไม่มีทางรู้ได้ว่าข้อใดข้อหนึ่งข้างต้นเป็นจริงดังนั้นความไว้วางใจจึงไม่เป็นไปโดยอัตโนมัติและมีการใช้ SOP ต้องได้รับอนุญาตอย่างชัดเจนก่อนที่เบราว์เซอร์จะให้ข้อมูลที่ได้รับไปยังเว็บไซต์อื่น


เหตุใดนโยบายแหล่งกำเนิดเดียวกันจึงใช้กับ JavaScript ในหน้าเว็บเท่านั้น

ส่วนขยายเบราว์เซอร์*แท็บเครือข่ายในเครื่องมือสำหรับนักพัฒนาเบราว์เซอร์และแอปพลิเคชันเช่น Postman ได้รับการติดตั้งซอฟต์แวร์ พวกเขาไม่ได้ส่งผ่านข้อมูลจากเว็บไซต์หนึ่งไปยัง JavaScript ที่เป็นของเว็บไซต์อื่นเพียงเพราะคุณเข้าชมเว็บไซต์อื่นนั้น การติดตั้งซอฟต์แวร์มักจะเป็นทางเลือกที่ใส่ใจมากกว่า

ไม่มีบุคคลที่สาม (Mallory) ที่ถือเป็นความเสี่ยง

*จำเป็นต้องเขียนส่วนขยายของเบราว์เซอร์อย่างระมัดระวังเพื่อหลีกเลี่ยงปัญหาข้ามแหล่งกำเนิด ดูเอกสาร Chrome สำหรับตัวอย่างเช่น


เหตุใดคุณจึงสามารถแสดงข้อมูลในเพจโดยไม่ต้องอ่านด้วย JS

มีหลายสถานการณ์ที่ไซต์ของ Mallory อาจทำให้เบราว์เซอร์ดึงข้อมูลจากบุคคลที่สามและแสดงข้อมูลนั้น (เช่นโดยการเพิ่ม<img>องค์ประกอบเพื่อแสดงภาพ) เป็นไปไม่ได้ที่ JavaScript ของ Mallory จะอ่านข้อมูลในทรัพยากรนั้นมีเพียงเบราว์เซอร์ของ Alice และเซิร์ฟเวอร์ของ Bob เท่านั้นที่สามารถทำได้ดังนั้นจึงยังปลอดภัย


CORS

Access-Control-Allow-OriginHTTP ตอบสนองส่วนหัวที่อ้างถึงในข้อผิดพลาดเป็นส่วนหนึ่งของล ธมาตรฐานซึ่งจะช่วยให้บ๊อบที่จะกำหนดให้ชัดเจนได้รับอนุญาตไปยังเว็บไซต์ของมัลลอที่จะเข้าถึงข้อมูลผ่านทางเบราว์เซอร์ของอลิซ

การใช้งานขั้นพื้นฐานจะรวมถึง:

Access-Control-Allow-Origin: *

…ในส่วนหัวของคำตอบเพื่ออนุญาตให้เว็บไซต์ใด ๆ อ่านข้อมูล

Access-Control-Allow-Origin: http://example.com/

…จะอนุญาตให้เฉพาะไซต์ใดไซต์หนึ่งเท่านั้นที่สามารถเข้าถึงได้และ Bob สามารถสร้างสิ่งนั้นแบบไดนามิกตามส่วนหัวของOrigin คำขอเพื่ออนุญาตให้หลายไซต์เข้าถึงได้ แต่ไม่ใช่ทั้งหมด

ข้อมูลเฉพาะของวิธีที่ Bob ตั้งค่าส่วนหัวการตอบกลับนั้นขึ้นอยู่กับเซิร์ฟเวอร์ HTTP ของ Bob และ / หรือภาษาโปรแกรมฝั่งเซิร์ฟเวอร์ มีชุดคำแนะนำสำหรับการกำหนดค่าทั่วไปต่างๆที่อาจช่วยได้

แบบจำลองที่ใช้กฎ CORS

หมายเหตุ: การร้องขอบางคนมีความซับซ้อนและส่งpreflight OPTIONS ขอให้เซิร์ฟเวอร์จะมีการตอบสนองต่อการเบราว์เซอร์ก่อนที่จะส่ง GET / POST / นำ / คำขอสิ่งที่ JS ต้องการที่จะทำให้ การใช้งาน CORS ที่เพิ่มAccess-Control-Allow-Originเฉพาะ URL ที่เฉพาะเจาะจงมักจะสะดุดด้วยสิ่งนี้


เห็นได้ชัดว่าการอนุญาตผ่าน CORS เป็นสิ่งที่ Bob จะทำได้ก็ต่อเมื่อ:

  • ข้อมูลไม่เป็นส่วนตัวหรือ
  • มัลลอรีได้รับความไว้วางใจ

แต่ฉันไม่ใช่บ็อบ!

ไม่มีกลไกมาตรฐานสำหรับMalloryในการเพิ่มส่วนหัวนี้เนื่องจากต้องมาจากเว็บไซต์ของ Bob ซึ่งเธอไม่ได้ควบคุม

หาก Bob กำลังเรียกใช้ API สาธารณะอาจมีกลไกในการเปิด CORS (อาจจะโดยการจัดรูปแบบคำขอด้วยวิธีใดวิธีหนึ่งหรือตัวเลือกการกำหนดค่าหลังจากเข้าสู่เว็บไซต์ Developer Portal สำหรับไซต์ของ Bob) สิ่งนี้จะต้องเป็นกลไกที่ Bob ดำเนินการ Mallory สามารถอ่านเอกสารในไซต์ของ Bob เพื่อดูว่ามีบางอย่างหรือไม่หรือเธอสามารถพูดคุยกับ Bob และขอให้เขาใช้ CORS


ข้อความแสดงข้อผิดพลาดที่กล่าวถึง "การตอบสนองสำหรับไฟล่วงหน้า"

ร้องขอบางแหล่งกำเนิดต่างประเทศจะถูกpreflighted

สิ่งนี้เกิดขึ้นเมื่อ (พูดโดยประมาณ) คุณพยายามร้องขอข้ามแหล่งที่มาที่:

  • รวมข้อมูลประจำตัวเช่นคุกกี้
  • ไม่สามารถสร้างด้วยรูปแบบ HTML ทั่วไป (เช่นมีส่วนหัวที่กำหนดเองหรือประเภทเนื้อหาที่คุณไม่สามารถใช้ในแบบฟอร์มได้enctype)

หากคุณกำลังทำสิ่งที่ต้องการแสงล่วงหน้าอย่างถูกต้อง

ในกรณีเหล่านี้แล้วส่วนที่เหลือของคำตอบนี้ยังคงใช้แต่คุณยังต้องให้แน่ใจว่าเซิร์ฟเวอร์สามารถฟังสำหรับการร้องขอ preflight (ซึ่งจะเป็นOPTIONS(และไม่ได้GET, POSTหรือสิ่งที่คุณกำลังพยายามที่จะส่ง) และตอบสนองต่อมันกับขวาAccess-Control-Allow-Originส่วนหัว แต่ยังAccess-Control-Allow-MethodsและAccess-Control-Allow-Headersเพื่ออนุญาตวิธีการหรือส่วนหัว HTTP เฉพาะของคุณ

หากคุณเรียกใช้ไฟล่วงหน้าโดยไม่ได้ตั้งใจ

บางครั้งผู้คนก็ทำผิดพลาดเมื่อพยายามสร้างคำขอของ Ajax และบางครั้งสิ่งเหล่านี้ทำให้เกิดความจำเป็นในการใช้ไฟล่วงหน้า หาก API ได้รับการออกแบบมาเพื่ออนุญาตคำขอข้ามแหล่งที่มา แต่ไม่ต้องการสิ่งใดที่จำเป็นต้องมีไฟล่วงหน้าสิ่งนี้จะทำลายการเข้าถึงได้

ข้อผิดพลาดทั่วไปที่ทำให้เกิดสิ่งนี้ ได้แก่ :

  • พยายามใส่Access-Control-Allow-Originและส่วนหัวการตอบสนอง CORS อื่น ๆ ตามคำขอ สิ่งเหล่านี้ไม่ได้อยู่ในคำขอไม่ทำอะไรที่เป็นประโยชน์ (ระบบการอนุญาตที่คุณสามารถให้สิทธิ์ตัวเองเป็นอย่างไร) และจะต้องปรากฏในการตอบกลับเท่านั้น
  • พยายามใส่Content-Type: application/jsonส่วนหัวในคำขอ GET ที่ไม่มีเนื้อหาของคำขอเพื่ออธิบายเนื้อหาของ (โดยทั่วไปเมื่อผู้เขียนสับสนContent-TypeและAccept)

ในทั้งสองกรณีนี้การลบส่วนหัวคำขอพิเศษมักจะเพียงพอที่จะหลีกเลี่ยงความจำเป็นในการใช้ไฟล่วงหน้า (ซึ่งจะช่วยแก้ปัญหาได้เมื่อสื่อสารกับ API ที่รองรับคำขอธรรมดา แต่ไม่ใช่คำขอที่มีการระบุไว้ล่วงหน้า)


การตอบสนองแบบทึบ

บางครั้งคุณต้องส่งคำขอ HTTP แต่คุณไม่จำเป็นต้องอ่านคำตอบ เช่นหากคุณโพสต์ข้อความบันทึกไปยังเซิร์ฟเวอร์เพื่อบันทึก

หากคุณกำลังใช้API (มากกว่า) แล้วคุณสามารถกำหนดค่าให้ไม่ได้พยายามที่จะใช้ล ธfetchXMLHttpRequest

โปรดทราบว่าสิ่งนี้จะไม่อนุญาตให้คุณทำอะไรที่คุณต้องการให้ CORS ทำ คุณจะไม่สามารถอ่านคำตอบได้ คุณจะไม่สามารถส่งคำขอที่ต้องใช้ไฟล่วงหน้าได้

จะช่วยให้คุณสามารถส่งคำขอแบบธรรมดาไม่เห็นการตอบกลับและไม่กรอกข้อความแสดงข้อผิดพลาดใน Developer Console

จะอธิบายได้อย่างไรโดยข้อความแสดงข้อผิดพลาดของ Chrome ที่ระบุเมื่อคุณส่งคำขอโดยใช้fetchและไม่ได้รับอนุญาตให้ดูการตอบกลับกับ CORS:

การเข้าถึงเพื่อดึงข้อมูลที่ ' https://example.com/' จากต้นทาง ' https://example.net' ถูกบล็อกโดยนโยบาย CORS: ไม่ ' Access-Control-Allow-Origin' แสดงอยู่ในทรัพยากรที่ร้องขอ หากการตอบกลับแบบทึบตอบสนองความต้องการของคุณให้ตั้งค่าโหมดของคำขอเป็น "no-cors" เพื่อดึงทรัพยากรโดยปิดใช้งาน CORS

ดังนั้น:

fetch("http://example.com", { mode: "no-cors" });

รายการทางเลือกสำหรับ CORS

JSONP

Bob ยังสามารถให้ข้อมูลโดยใช้การแฮ็กเช่นJSONPซึ่งเป็นวิธีที่ผู้คนทำ Ajax ข้ามแหล่งกำเนิดก่อนที่ CORS จะเข้ามา

ทำงานโดยการนำเสนอข้อมูลในรูปแบบของโปรแกรม JavaScript ที่ฉีดข้อมูลลงในหน้าของ Mallory

ต้องให้ Mallory ไว้วางใจ Bob ไม่ให้ส่งโค้ดที่เป็นอันตราย

หมายเหตุธีมทั่วไป: ไซต์ที่ให้ข้อมูลจะต้องแจ้งให้เบราว์เซอร์ทราบว่าไซต์ของบุคคลที่สามสามารถเข้าถึงข้อมูลที่ส่งไปยังเบราว์เซอร์ได้

เนื่องจาก JSONP ทำงานโดยการต่อท้าย<script>องค์ประกอบเพื่อโหลดข้อมูลในรูปแบบของโปรแกรม JavaScript ซึ่งเรียกใช้ฟังก์ชันที่มีอยู่แล้วในเพจการพยายามใช้เทคนิค JSONP กับ URL ที่ส่งคืน JSON จะล้มเหลวโดยทั่วไปจะมีข้อผิดพลาด CORB เนื่องจาก JSON ไม่ใช่ JavaScript

ย้ายทรัพยากรทั้งสองไปยังแหล่งกำเนิดเดียว

หากเอกสาร HTML ที่ JS ทำงานอยู่และ URL ที่ร้องขออยู่ในต้นทางเดียวกัน (ใช้โครงร่างชื่อโฮสต์และพอร์ตเดียวกันร่วมกัน) นโยบายแหล่งกำเนิดเดียวกันจะให้สิทธิ์ตามค่าเริ่มต้น ไม่จำเป็นต้องใช้ CORS

พร็อกซี

Mallory สามารถใช้รหัสฝั่งเซิร์ฟเวอร์เพื่อดึงข้อมูล (ซึ่งเธอสามารถส่งจากเซิร์ฟเวอร์ของเธอไปยังเบราว์เซอร์ของ Alice ผ่าน HTTP ได้ตามปกติ)

มันจะ:

  • เพิ่มส่วนหัว CORS
  • แปลงการตอบสนองเป็น JSONP
  • มีอยู่ในแหล่งกำเนิดเดียวกันกับเอกสาร HTML

โค้ดฝั่งเซิร์ฟเวอร์นั้นสามารถเขียนและโฮสต์โดยบุคคลที่สามได้ (เช่น CORS Anywhere) สังเกตผลกระทบของความเป็นส่วนตัว: บุคคลที่สามสามารถตรวจสอบได้ว่าใครเป็นผู้รับมอบฉันทะในเซิร์ฟเวอร์ของตน

Bob ไม่จำเป็นต้องให้สิทธิ์ใด ๆ เพื่อให้สิ่งนั้นเกิดขึ้น

ไม่มีผลกระทบด้านความปลอดภัยที่นี่เนื่องจากเป็นเพียงระหว่างมัลลอรีและบ็อบ ไม่มีทางที่บ็อบจะคิดว่ามัลลอรีเป็นอลิซและมอบข้อมูลที่ควรเก็บเป็นความลับระหว่างอลิซและบ็อบให้แก่มัลลอรี

ดังนั้น Mallory สามารถใช้เทคนิคนี้เพื่ออ่านข้อมูลสาธารณะเท่านั้น

อย่างไรก็ตามโปรดทราบว่าการนำเนื้อหาจากเว็บไซต์ของผู้อื่นมาแสดงและแสดงด้วยตนเองอาจเป็นการละเมิดลิขสิทธิ์และเปิดโอกาสให้คุณดำเนินการทางกฎหมายได้

การเขียนสิ่งอื่นที่ไม่ใช่เว็บแอป

ดังที่ระบุไว้ในส่วน "เหตุใดนโยบายแหล่งกำเนิดเดียวกันจึงใช้ได้กับ JavaScript ในหน้าเว็บเท่านั้น" คุณสามารถหลีกเลี่ยง SOP ได้โดยไม่เขียน JavaScript ในหน้าเว็บ

ไม่ได้หมายความว่าคุณจะใช้ JavaScript และ HTML ต่อไปไม่ได้ แต่คุณสามารถแจกจ่ายโดยใช้กลไกอื่น ๆ เช่น Node-WebKit หรือ PhoneGap

ส่วนขยายของเบราว์เซอร์

เป็นไปได้ที่ส่วนขยายของเบราว์เซอร์จะฉีดส่วนหัว CORS ในการตอบสนองก่อนที่จะใช้นโยบายแหล่งกำเนิดเดียวกัน

สิ่งเหล่านี้มีประโยชน์สำหรับการพัฒนา แต่ไม่สามารถใช้งานได้จริงสำหรับไซต์ที่ใช้งานจริง (การขอให้ผู้ใช้ไซต์ของคุณทุกคนติดตั้งส่วนขยายเบราว์เซอร์ที่ปิดใช้งานคุณลักษณะด้านความปลอดภัยของเบราว์เซอร์นั้นไม่สมเหตุสมผล)

นอกจากนี้ยังมีแนวโน้มที่จะทำงานเฉพาะกับคำขอธรรมดา ๆ เท่านั้น (ล้มเหลวเมื่อจัดการคำขอของ OPTIONS ล่วงหน้า)

การมีสภาพแวดล้อมการพัฒนาที่เหมาะสมกับเซิร์ฟเวอร์การพัฒนา เฉพาะที่เป็นแนวทางที่ดีกว่า


ความเสี่ยงด้านความปลอดภัยอื่น ๆ

โปรดทราบว่า SOP / CORS ไม่ลดการโจมตีXSS , CSRFหรือSQL Injectionซึ่งจำเป็นต้องจัดการอย่างอิสระ


สรุป

  • ไม่มีอะไรที่คุณสามารถทำได้ในโค้ดฝั่งไคลเอ็นต์ของคุณที่จะทำให้ CORS เข้าถึงเซิร์ฟเวอร์ของคนอื่นได้
  • หากคุณควบคุมเซิร์ฟเวอร์จะมีการร้องขอ: เพิ่มสิทธิ์ CORS ให้กับเซิร์ฟเวอร์
  • หากคุณเป็นมิตรกับบุคคลที่ควบคุม: ให้พวกเขาเพิ่มสิทธิ์ CORS ให้กับมัน
  • หากเป็นบริการสาธารณะ:
    • อ่านเอกสาร API เพื่อดูว่าพวกเขาพูดอย่างไรเกี่ยวกับการเข้าถึงด้วย JavaScript ฝั่งไคลเอ็นต์:
      • พวกเขาอาจบอกให้คุณใช้ URL เฉพาะ
      • อาจรองรับ JSONP
      • อาจไม่รองรับการเข้าถึงข้ามแหล่งที่มาจากโค้ดฝั่งไคลเอ็นต์เลย (อาจเป็นการตัดสินใจโดยเจตนาเกี่ยวกับเหตุผลด้านความปลอดภัยโดยเฉพาะอย่างยิ่งหากคุณต้องส่งคีย์ API ส่วนบุคคลในแต่ละคำขอ)
    • ตรวจสอบว่าคุณไม่ได้เรียกใช้คำขอไฟล่วงหน้าที่คุณไม่ต้องการ API อาจให้สิทธิ์สำหรับคำขอธรรมดา แต่ไม่ใช่คำขอที่เน้นไว้ล่วงหน้า
  • หากไม่ตรงตามข้อใดข้างต้นให้ใช้เบราว์เซอร์เพื่อคุยกับเซิร์ฟเวอร์ของคุณแทนจากนั้นให้เซิร์ฟเวอร์ของคุณดึงข้อมูลจากเซิร์ฟเวอร์อื่นและส่งต่อไป (นอกจากนี้ยังมีบริการโฮสต์ของบุคคลที่สามซึ่งแนบส่วนหัว CORS เข้ากับทรัพยากรที่เข้าถึงได้แบบสาธารณะซึ่งคุณสามารถใช้ได้)

ถ้าฉันเรียกใช้ LAN ท้องถิ่นบนเว็บเซิร์ฟเวอร์และพยายามทำการโหลด ajax จาก IP / URL จะใช้งานได้หรือไม่ ฉันยังไม่ได้ลอง เนื่องจากเว็บเซิร์ฟเวอร์ของฉันเก็บข้อมูล json จะเป็น MCU
Ciasto piekarz

@Ciastopiekarz - ใช้ต้นกำเนิดเดียวกัน / กฎแหล่งกำเนิดที่แตกต่างกัน ใช้กฎการกำหนดเส้นทางเครือข่ายปกติ
Quentin

26
คำตอบที่สมบูรณ์ที่สุดที่ฉันเคยอ่านแทนที่จะเป็นเพียงลิงค์เกี่ยวกับ cors ..
pungggi

@Quentin - ว้าว! +1! สิ่งที่ฉันต้องเข้าใจคือถ้า Alice ใช้ส่วนขยาย CORS เซิร์ฟเวอร์คิดว่าการโทร http ของเธอไม่ได้มาจาก javascript แต่มาจากส่วนขยายของเบราว์เซอร์และถือว่าเป็นคำขอต้นทางเดียวกันหรือไม่
snippetkid

@snippetkid - ไม่ในกรณีปกติเซิร์ฟเวอร์จะส่งส่วนหัว CORS เพื่อตอบสนองตลอดเวลาและไม่สนใจว่าคำขอนั้นมาจากที่ใด เป็นความรับผิดชอบของเบราว์เซอร์ในการอนุญาตหรือปฏิเสธการเข้าถึงข้อมูลไปยัง JS ตามส่วนหัว CORS ในการตอบสนอง (สิ่งต่าง ๆ ได้รับ / เล็กน้อย / ซับซ้อนมากขึ้นบนเซิร์ฟเวอร์เมื่อมันมาถึงคำขอไฟล่วงหน้า)
Quentin

3

เซิร์ฟเวอร์เป้าหมายต้องอนุญาตคำขอข้ามแหล่งที่มา หากต้องการอนุญาตผ่าน Express เพียงจัดการคำขอตัวเลือก http:

app.options('/url...', function(req, res, next){
   res.header('Access-Control-Allow-Origin', "*");
   res.header('Access-Control-Allow-Methods', 'POST');
   res.header("Access-Control-Allow-Headers", "accept, content-type");
   res.header("Access-Control-Max-Age", "1728000");
   return res.sendStatus(200);
});

3

เนื่องจากไม่ได้ระบุไว้ในคำตอบที่ยอมรับ

  • นี่ไม่ใช่กรณีของคำถามที่แน่นอน แต่อาจช่วยผู้อื่นที่ค้นหาปัญหานั้นได้
  • นี่คือสิ่งที่คุณสามารถทำได้ในลูกค้ารหัสของคุณเพื่อป้องกันข้อผิดพลาด ธ ในบางกรณี

คุณสามารถใช้คำขอแบบธรรมดาได้
ในการดำเนินการ 'คำขอธรรมดา' คำขอจะต้องเป็นไปตามเงื่อนไขหลายประการ เช่นเดียวที่ช่วยให้POST, GETและHEADวิธีการเช่นเดียวกับการอนุญาตให้เพียงบางส่วนที่ได้รับส่วนหัว (คุณสามารถหาเงื่อนไขทั้งหมดที่นี่ )

หากรหัสไคลเอ็นต์ของคุณไม่ได้ตั้งค่าส่วนหัวที่ได้รับผลกระทบอย่างชัดเจน (เช่น "ยอมรับ") พร้อมกับค่าแก้ไขในคำขออาจเกิดขึ้นได้ว่าไคลเอ็นต์บางรายตั้งค่าส่วนหัวเหล่านี้โดยอัตโนมัติด้วยค่า "ที่ไม่เป็นมาตรฐาน" บางค่าทำให้เซิร์ฟเวอร์ไม่ยอมรับเป็น คำขออย่างง่าย - ซึ่งจะทำให้คุณมีข้อผิดพลาด CORS


2

สิ่งนี้เกิดขึ้นเนื่องจากข้อผิดพลาด CORS CORS ย่อมาจาก Cross Origin Resource Sharing กล่าวง่ายๆข้อผิดพลาดนี้เกิดขึ้นเมื่อเราพยายามเข้าถึงโดเมน / ทรัพยากรจากโดเมนอื่น

อ่านเพิ่มเติมได้ที่นี่: ข้อผิดพลาด CORS กับ jquery

ในการแก้ไขปัญหานี้หากคุณสามารถเข้าถึงโดเมนอื่นได้คุณจะต้องอนุญาต Access-Control-Allow-Origin ในเซิร์ฟเวอร์ สามารถเพิ่มในส่วนหัว คุณสามารถเปิดใช้งานสิ่งนี้สำหรับคำขอ / โดเมนทั้งหมดหรือโดเมนเฉพาะ

วิธีรับคำขอโพสต์การแบ่งปันทรัพยากรข้ามแหล่งที่มา (CORS)

ลิงก์เหล่านี้อาจช่วยได้


0

ปัญหา CORS นี้ไม่ได้อธิบายเพิ่มเติม (สำหรับสาเหตุอื่น ๆ )

ขณะนี้ฉันมีปัญหานี้อยู่ภายใต้เหตุผลอื่น ส่วนหน้าของฉันส่งคืนข้อผิดพลาดส่วนหัว 'Access-Control-Allow-Origin' เช่นกัน

เพียงแค่ฉันชี้ URL ผิดดังนั้นส่วนหัวนี้จึงไม่แสดงอย่างถูกต้อง (ซึ่งฉันคิดว่ามันทำ) localhost (ส่วนหน้า) -> เรียกไปยัง http ที่ไม่ปลอดภัย (ควรเป็น https) ตรวจสอบให้แน่ใจว่าจุดสิ้นสุดของ API จากส่วนหน้าชี้ไปยังโปรโตคอลที่ถูกต้อง


0

ฉันพบข้อผิดพลาดเดียวกันในคอนโซล Chrome

ปัญหาของฉันก็คือฉันได้พยายามที่จะไปที่เว็บไซต์ที่ใช้แทนhttp:// https://ดังนั้นจึงไม่มีอะไรต้องแก้ไขเพียงแค่ไปที่ไซต์เดียวกันโดยใช้httpsไฟล์.


0

ข้อผิดพลาดนี้ทำให้ฉันเสียเวลา 2 วัน ฉันตรวจสอบบันทึกเซิร์ฟเวอร์ของฉันคำขอ / การตอบสนองตัวเลือก Preflight ระหว่างเบราว์เซอร์ Chrome / Edge และเซิร์ฟเวอร์ก็ใช้ได้ เหตุผลหลักคือการตอบสนองของเซิร์ฟเวอร์ GET / POST / PUT / DELETE สำหรับ XHTMLRequest ต้องมีส่วนหัวต่อไปนี้:

access-control-allow-origin: origin  

"origin" อยู่ในส่วนหัวของคำขอ (เบราว์เซอร์จะเพิ่มเพื่อขอให้คุณ) ตัวอย่างเช่น:

Origin: http://localhost:4221

คุณสามารถเพิ่มส่วนหัวการตอบกลับดังต่อไปนี้เพื่อยอมรับสำหรับทุกคน:

access-control-allow-origin: *  

หรือส่วนหัวการตอบกลับสำหรับคำขอเฉพาะเช่น:

access-control-allow-origin: http://localhost:4221 

ข้อความในเบราว์เซอร์ไม่ชัดเจนที่จะเข้าใจ: "... ทรัพยากรที่ร้องขอ"

โปรดทราบว่า: CORS ทำงานได้ดีสำหรับ localhost พอร์ตที่แตกต่างกันหมายถึงโดเมนที่แตกต่างกัน หากคุณได้รับข้อความแสดงข้อผิดพลาดให้ตรวจสอบการกำหนดค่า CORS ทางฝั่งเซิร์ฟเวอร์


-1

คำขอ "รับ" พร้อมต่อท้ายส่วนหัวจะเปลี่ยนเป็นคำขอ "ตัวเลือก" ปัญหานโยบาย Cors จึงเกิดขึ้น คุณต้องใช้คำขอ "ตัวเลือก" กับเซิร์ฟเวอร์ของคุณ


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.