CORS ร้ายแรงเมื่อ http: // localhost เป็นจุดกำเนิด


186

ฉันติดอยู่กับปัญหา CORS นี้แม้ว่าฉันจะตั้งเซิร์ฟเวอร์ (nginx / node.js) ด้วยส่วนหัวที่เหมาะสม

ฉันเห็นในบานหน้าต่างเครือข่าย Chrome -> ส่วนหัวการตอบกลับ:

Access-Control-Allow-Origin:http://localhost

ซึ่งควรทำเคล็ดลับ

นี่คือรหัสที่ฉันใช้ในการทดสอบ:

var xhr = new XMLHttpRequest();
xhr.onload = function() {
   console.log('xhr loaded');
};
xhr.open('GET', 'http://stackoverflow.com/');
xhr.send();

ฉันเข้าใจ

XMLHttpRequest ไม่สามารถโหลดhttp://stackoverflow.com/ Origin http: // localhostไม่ได้รับอนุญาตจาก Access-Control-Allow-Origin

ฉันสงสัยว่าเป็นปัญหาในสคริปต์ไคลเอ็นต์และไม่ใช่การกำหนดค่าเซิร์ฟเวอร์ ...


44
ไม่ stackoverflow.com ต้องตั้งค่าส่วนหัวนี้ไม่ใช่คุณ : x สิ่งที่จะเป็นจุดกำเนิดของนโยบายเดียวกันนี้เป็นอย่างอื่น
Esailija

3
ลองเข้าถึงเซิร์ฟเวอร์ที่คุณตั้งค่าไว้ไม่ให้ล้นมากเกินไป ;)
Nek

DOH! มีวิธีบอก chrome (หรือเบราว์เซอร์อื่น) เพื่อให้ได้ทรัพยากรแม้ว่าส่วนหัวจะหายไปเมื่อต้นกำเนิดของฉันคือ localhost หรือไม่
Whadar

เรียกใช้รหัสของคุณใน Chrome (20.0.1132.57, Windows 7) ทำงานได้ดี
imwilsonxu

1
หากคุณกำลังใช้ localhost กับพอร์ตคำตอบนี้ทำงานให้ฉันserverfault.com/a/673551/238261
Nelu

คำตอบ:


230

Chrome ไม่รองรับ localhost สำหรับคำขอ CORS (ข้อผิดพลาดที่เปิดในปี 2010 ทำเครื่องหมาย WontFix ในปี 2014)

ในการหลีกเลี่ยงสิ่งนี้คุณสามารถใช้โดเมนเช่นlvh.me(ซึ่งมีคะแนนที่ 127.0.0.1 เช่นเดียวกับ localhost) หรือเริ่มโครเมี่ยมด้วยการ--disable-web-securityตั้งค่าสถานะ (สมมติว่าคุณกำลังทดสอบ)


24
@greensuisse - ไม่ได้โพสต์ลงใน localhost มันโพสต์จาก localhost ที่เป็นปัญหา
Cheeso

9
ข้อผิดพลาดนั้นไม่ถูกต้อง (และถูกทำเครื่องหมายเป็น - crbug.com/67743#c17 ) ความคิดเห็นของ Esailijaนั้นถูกต้องการเพิ่มส่วนหัวเหล่านี้ไปยัง localhost จะไม่ช่วยให้คุณเข้าถึงเว็บไซต์อื่น ๆ ได้อย่างน่าอัศจรรย์ เป็นไซต์ระยะไกลที่ต้องให้บริการกับส่วนหัวเหล่านี้
Rob W

22
ใช้เวลาเพียง 2 ชั่วโมงในการทดสอบ Chrome เพื่อรับรู้ว่ามันทำงานได้ดีอย่างสมบูรณ์ใน Firefox ..Grrrr...
FloatingRock

11
ตัวเลือกอื่น ๆ : แก้ไขไฟล์โฮสต์ของคุณเพื่อให้ท้องถิ่น [mysite] .com ชี้ไปที่ 127.0.0.1 จากนั้นให้อนุญาตไฟล์ CORS ของคุณ *. [mysite] .com
ทอม

6
ฉันประสบปัญหาเดียวกันกับ FireFox ฉันทำได้แค่ Edge! แม้ว่าจะโพสต์ดีน่าอัศจรรย์! :)
Luis Gouveia

54

ตามคำตอบของ @ Beau Chrome ไม่สนับสนุนการร้องขอ localhost CORS และไม่น่าจะมีการเปลี่ยนแปลงใด ๆ ในทิศทางนี้

ฉันใช้Allow-Control-Allow-Origin: * ส่วนขยายของ Chromeเพื่อแก้ไขปัญหานี้ ส่วนขยายจะเพิ่มส่วนหัว HTTP ที่จำเป็นสำหรับ CORS:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: "GET, PUT, POST, DELETE, HEAD, OPTIONS"
Access-Control-Expose-Headers: <you can add values here>

รหัสที่มามีการเผยแพร่บน Github

โปรดทราบว่าส่วนขยายจะกรอง URL ทั้งหมดตามค่าเริ่มต้น สิ่งนี้อาจทำให้บางเว็บไซต์เสียหาย (ตัวอย่างเช่น: Dropbox) ฉันได้เปลี่ยนไปกรองเพียงlocalhost URL ที่มีตัวกรอง URL ต่อไปนี้

*://localhost:*/*

14
หากคุณอ่านปัญหา @beau ลิงก์ไปยังคุณจะเห็นว่า Chrome 100% รองรับการร้องขอข้ามทางไปและกลับจาก localhost ปัญหาถูกปิดในปี 2014 เพราะไม่สามารถทำซ้ำได้ เสียงที่เหลือในเธรดนั้นคือผู้ที่มีเซิร์ฟเวอร์ที่ไม่ได้กำหนดค่าผิด (เช่นเดียวกับคำถามดั้งเดิมที่นี่)
Molomby

1
ทำงานเหมือนเสน่ห์สำหรับฉันในโครเมี่ยม
Aakash สหาย

2

3
ส่วนขยายนี้ไม่ได้ทำงานกับAccess-Control-Allow-Credentials: trueเพราะมันชุดAccess-Control-Allow-Originไป*และมีทั้งtrueและ*ถูกบล็อกโดยเบราว์เซอร์ หากใช้ข้อมูลประจำตัวจริงคุณต้องใช้ต้นกำเนิดที่ไม่ใช่ตัวแทน ฉันแนะนำ Moesif Origins และ CORS Changer Extension ซึ่งให้คุณเปลี่ยนหัวได้ตามต้องการ
ซามูเอล

บางทีฉันอาจทำสิ่งผิดปกติ แต่ส่วนขยายนี้ดูเหมือนจะไม่เหมาะกับฉันอีกต่อไป
James Parker

19

ปัญหาที่แท้จริงคือถ้าเราตั้งค่า-Allow-สำหรับคำขอทั้งหมด ( OPTIONS& POST) Chrome จะยกเลิก รหัสต่อไปนี้ใช้งานได้กับPOSTLocalHost ด้วย Chrome

<?php
if (isset($_SERVER['HTTP_ORIGIN'])) {
    //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header("Access-Control-Allow-Origin: *");
    header('Access-Control-Allow-Credentials: true');    
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
}   
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    exit(0);
} 
?>

15
OP ใช้ nginx / node.js ไม่ใช่ PHP
code_monk

4

Chrome จะทำการร้องขอกับ CORS จากlocalhostแหล่งกำเนิดได้ดี นี่ไม่ใช่ปัญหาของ Chrome

เหตุผลที่คุณไม่สามารถโหลดได้http://stackoverflow.comคือAccess-Control-Allow-Originส่วนหัวไม่อนุญาตlocalhostแหล่งกำเนิดของคุณ


2

การแก้ไขส่วนขยาย Chrome ที่รวดเร็วและสกปรก:

Moesif Orign & CORS Changer

อย่างไรก็ตาม Chrome รองรับการร้องขอข้ามทางจาก localhost ให้แน่ใจว่าจะเพิ่มส่วนหัวสำหรับสำหรับAccess-Control-Allow-Originlocalhost


ฉันเพิ่มส่วนขยายนี้ใน Opera ของฉันและตอนนี้มันเพิ่มขึ้น ฉันไม่สามารถบอกได้ว่าเมื่อใดที่เปิดและปิดดังนั้นฉันจึงใช้ Firefox สำหรับการทำงาน และโอเปร่าเพื่อการพัฒนา google suit ไม่ชอบและสิ่งอื่น ๆ ก็ไม่เหมือนกัน
Maddocks

1

ไม่มีส่วนขยายใดที่เหมาะกับฉันดังนั้นฉันจึงติดตั้งพรอกซีท้องถิ่นอย่างง่าย ในกรณีของฉันhttps://www.npmjs.com/package/local-cors-proxy เป็นการตั้งค่า 2 นาที:

(จากเว็บไซต์ของพวกเขา)

npm install -g local-cors-proxy

API endpoint ที่เราต้องการขอให้มีปัญหา CORS: https://www.yourdomain.ie/movies/list

เริ่มต้นพร็อกซี: lcp --proxyUrl https://www.yourdomain.ie

จากนั้นในรหัสลูกค้าของคุณจุดสิ้นสุด API ใหม่: http://localhost:8010/proxy/movies/list

ทำงานได้อย่างมีเสน่ห์สำหรับฉัน: แอปของคุณโทรหาพร็อกซีที่โทรหาเซิร์ฟเวอร์ ปัญหาศูนย์ CORS


0

ฉันตัดสินใจที่จะไม่แตะที่ส่วนหัวและทำการเปลี่ยนเส้นทางที่ฝั่งเซิร์ฟเวอร์แทนและมันก็เหมือนมีเสน่ห์

ตัวอย่างด้านล่างนี้สำหรับ Angular รุ่นปัจจุบัน (ปัจจุบัน 9) และเฟรมเวิร์กอื่น ๆ ที่ใช้ webpacks DevServer แต่ฉันคิดว่าหลักการเดียวกันนี้จะใช้ได้กับแบ็กเอนด์อื่น ๆ

ดังนั้นฉันจะใช้การกำหนดค่าต่อไปนี้ในไฟล์proxy.conf.json :

{
  "/api": {
    "target": "http://localhost:3000",
    "pathRewrite": {"^/api" : ""},
   "secure": false
 }
}

ในกรณีของ Angular ฉันให้บริการกับการกำหนดค่านั้น:

$ ng serve -o --proxy-config=proxy.conf.json

ฉันชอบที่จะใช้พร็อกซี่ในคำสั่งบริการ แต่คุณอาจนำการกำหนดค่านี้ไปที่angular.jsonดังนี้:

"architect": {
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": {
      "browserTarget": "your-application-name:build",
      "proxyConfig": "src/proxy.conf.json"
    },

ดูสิ่งนี้ด้วย:

https://www.techiediaries.com/fix-cors-with-angular-cli-proxy-configuration/

https://webpack.js.org/configuration/dev-server/#devserverproxy

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