Origin <origin> ไม่ได้รับอนุญาตจาก Access-Control-Allow-Origin


184
XMLHttpRequest cannot load http://localhost:8080/api/test. Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. 

ฉันอ่านเกี่ยวกับคำขออาแจ็กซ์ข้ามโดเมนและเข้าใจปัญหาความปลอดภัยพื้นฐาน ในกรณีของฉันมีเซิร์ฟเวอร์ 2 เครื่องกำลังทำงานอยู่ภายในเครื่องและต้องการเปิดใช้งานคำขอข้ามโดเมนระหว่างการทดสอบ

localhost:8080 - Google Appengine dev server
localhost:3000 - Node.js server

ฉันกำลังออกคำร้องขอ ajax localhost:8080 - GAE serverขณะที่เพจของฉันโหลดจากเซิร์ฟเวอร์โหนด สิ่งที่ง่ายที่สุดและปลอดภัยที่สุด (ไม่ต้องการเริ่มด้วยdisable-web-securityตัวเลือกchrome ) ถ้าฉันต้องเปลี่ยน'Content-Type'ฉันควรทำที่โหนดเซิร์ฟเวอร์หรือไม่ อย่างไร?


วิธีแก้ปัญหาที่เร็วกว่าสามารถพบได้ที่นี่: stackoverflow.com/a/21622564/4455570
Gabriel Wamunyu

คำตอบ:


195

เนื่องจากพวกเขากำลังทำงานอยู่บนพอร์ตที่แตกต่างกันที่พวกเขาจะแตกต่างกัน originJavaScript ไม่สำคัญว่าพวกเขาอยู่ในเครื่อง / ชื่อโฮสต์เดียวกัน

คุณต้องเปิดใช้งาน CORS บนเซิร์ฟเวอร์ (localhost: 8080) ลองชมไซต์นี้: http://enable-cors.org/

สิ่งที่คุณต้องทำคือเพิ่มส่วนหัว HTTP ไปยังเซิร์ฟเวอร์:

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

หรือเพื่อความเรียบง่าย:

Access-Control-Allow-Origin: *

คิดว่าอย่าใช้ "*" หากเซิร์ฟเวอร์ของคุณพยายามตั้งค่าคุกกี้และคุณใช้ withCredentials = true

เมื่อตอบสนองต่อการร้องขอข้อมูลประจำตัวเซิร์ฟเวอร์ต้องระบุโดเมนและไม่สามารถใช้ไวด์การ์ด

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับwithCredentialsที่นี่


ถ้าเราต้องการเพิ่มส่วนหัวนี้ลงใน HTML แล้วเราควรทำอย่างไร
Azam Alvi

1
ฉันไม่คิดว่าพอร์ตนั้นจำเป็น แต่ถ้าคุณใช้พอร์ตที่ไม่ได้มาตรฐานเช่น 3000 คุณต้องรวมไว้ในนโยบาย CORS
Michael Connor

4
ขอบคุณสำหรับคำตอบนี้ เพียงแค่ต้องการเน้นผลกระทบด้านความปลอดภัยของการใช้ '*' เป็นค่าที่นี่ สิ่งนี้ทำให้ต้นกำเนิดทั้งหมด: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ ...... ดูเหมือนว่าตัวอย่างแรกจะดีที่สุดในแง่ของการเข้าถึงน้อยที่สุด รายละเอียดเกี่ยวกับวิธีการทำเช่นนี้กับหลายโดเมนที่นี่: stackoverflow.com/a/1850482/1566623
Christopher Kuttruff

14
เพื่อความชัดเจนเมื่อมีการกล่าวว่าคุณจำเป็นต้อง "เพิ่มส่วนหัว HTTP ไปยังเซิร์ฟเวอร์" หมายความว่าAccess-Control-Allow-Originส่วนหัวที่กำหนดต้องเป็นส่วนหัวที่เพิ่มเข้ากับการตอบสนอง HTTP ที่เซิร์ฟเวอร์ส่ง หัวข้อนี้ต้องการที่จะเป็นส่วนหนึ่งของการตอบสนองของเซิร์ฟเวอร์ก็ไม่จำเป็นต้องเป็นส่วนหนึ่งของคำขอของลูกค้า สิ่งที่เกิดขึ้นก่อนที่ลูกค้าจะทำคำขอจริงที่คุณต้องการเบราว์เซอร์จะส่งOPTIONSคำขอมาก่อนและหากการตอบสนองของเซิร์ฟเวอร์ต่อOPTIONSคำขอนั้นไม่มีส่วนหัวเบราว์เซอร์จะไม่ส่งคำขอที่คุณต้องการ
AjaxLeung

1
เป็นสิ่งสำคัญในการอ่านเคล็ดลับที่เกี่ยวข้องสำหรับเซิร์ฟเวอร์เบื้องหลังที่ enable-cors.org
Karlth

69

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

ส่วนขยายของ Chrome อนุญาต - ควบคุม - อนุญาต - กำเนิด: *


6
ฉันไม่รู้ว่าทำไมคุณไม่ได้รับการโหวตมากขึ้น นี่เป็นสิ่งที่รบกวนน้อยที่สุดสำหรับการพัฒนาบน localhost ด้วย Chrome
David Betz

เห็นด้วยอย่างแน่นอน เปิดใช้งานง่ายสำหรับ localhost dev กับเซิร์ฟเวอร์ระยะไกลโดยไม่ต้องเปลี่ยนการกำหนดค่าสำหรับเซิร์ฟเวอร์ระยะไกล
Jens Wegar

@DavidBetz: พิจารณาว่าคุณยืนยันส่วนขยายและไว้วางใจแน่นอน;)
haylem

2
นี่น่าจะเป็นคำตอบยอดนิยม! โดยเฉพาะอย่างยิ่งที่ localhost เป็นห่วง
นายเบเนดิกต์

16
หากนี่เป็นวิธีแก้ปัญหาที่ดี CORS จะไม่ถูกคิดค้นตั้งแต่แรก การใช้ส่วนหัวนี้กับโฮสต์ใด ๆ ปิดการใช้งานการป้องกัน CORS และทำให้คุณมีสคริปต์ที่เป็นอันตรายไม่ใช่เฉพาะของคุณ อย่าแปลกใจถ้าบัญชีธนาคารของคุณว่างเปล่า
dolmen

54

คุณต้องเปิดใช้งาน CORS เพื่อแก้ไขปัญหานี้

หากแอปของคุณถูกสร้างขึ้นด้วย node.js ง่าย ๆ

ตั้งค่าในส่วนหัวการตอบสนองของคุณเช่น

var http = require('http');

http.createServer(function (request, response) {
response.writeHead(200, {
    'Content-Type': 'text/plain',
    'Access-Control-Allow-Origin' : '*',
    'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE'
});
response.end('Hello World\n');
}).listen(3000);

หากแอปของคุณถูกสร้างด้วยเฟรมเวิร์คด่วน

ใช้มิดเดิลแวร์ CORS อย่าง

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', "*");
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
}

และสมัครผ่านทาง

app.configure(function() {
    app.use(allowCrossDomain);
    //some other code
});    

นี่คือลิงก์อ้างอิงสองลิงก์

  1. วิธีที่จะช่วยให้-ล ธ อินด่วน nodejs
  2. ไดรฟ์ลงในโหนด -js -very-first-app # ดูส่วน Ajax

config.allowedDomainsคุณสามารถระบุวิธีการใช้ พูดในกรณีของฉันฉันควรใส่อะไร uri
bsr

@bsr: คุณสามารถใช้*หรือspecific domainคุณต้องการให้สิทธิ์การเข้าถึง
mithunsatheesh

1
ดังนั้นฉันคนเดียวที่ได้รับapp.configure()ไม่ใช่ข้อผิดพลาดของฟังก์ชั่น?
Pramesh Bajracharya

@PrameshBajrachaya ฉันไม่ได้รวมส่วน "app.configure" - เพียง "app.use (allowCrossDomain)" และมันใช้งานได้สำหรับฉัน
Giorgos Sfikas

8

ฉันยอมรับคำตอบของ @Rocket hazmat เพราะมันนำฉันไปสู่ทางออก เป็นจริงบนเซิร์ฟเวอร์ GAE ฉันต้องการตั้งค่าส่วนหัว ฉันต้องตั้งค่าเหล่านี้

"Access-Control-Allow-Origin" -> "*"
"Access-Control-Allow-Headers" -> "Origin, X-Requested-With, Content-Type, Accept"

การตั้งค่า"Access-Control-Allow-Origin" ให้ข้อผิดพลาดเท่านั้น

Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers.

นอกจากนี้หากต้องส่งโทเค็นรับรองความถูกต้องให้เพิ่มสิ่งนี้ด้วย

"Access-Control-Allow-Credentials" -> "true"

นอกจากนี้ที่ลูกค้ากำหนด withCredentials

นี้ทำให้ 2 OPTIONSการร้องขอไปยังส่งไปยังเซิร์ฟเวอร์หนึ่งที่มี การตรวจสอบความถูกต้องของคุกกี้ไม่ได้ถูกส่งไปด้วยดังนั้นจึงต้องปฏิบัติต่อการตรวจสอบภายนอก


7

ใน router.js เพียงแค่เพิ่มรหัสก่อนที่จะเรียกวิธีการรับ / โพสต์ มันเหมาะกับฉันโดยไม่มีข้อผิดพลาด

//Importing modules @Brahmmeswar
const express = require('express');
const router = express.Router();

const Contact = require('../models/contacts');

router.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
  });

5

ฉันกำลังประสบปัญหาในขณะที่เรียกทรัพยากรต้นกำเนิดโดยใช้ Ajax จากโครเมี่ยม

ฉันใช้โหนด js และเซิร์ฟเวอร์ http ท้องถิ่นเพื่อปรับใช้แอปโหนด js ของฉัน

ฉันได้รับการตอบกลับข้อผิดพลาดเมื่อฉันเข้าใช้ทรัพยากรข้ามแหล่งกำเนิด

ฉันพบวิธีแก้ปัญหาอย่างหนึ่ง

1) ฉันได้เพิ่มรหัสด้านล่างลงในไฟล์ app.js ของฉัน

res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");

2) ในหน้า html ของฉันเรียกว่าการใช้ทรัพยากรต้นกำเนิดโดยใช้ $.getJSON();

$.getJSON("http://localhost:3000/users", function (data) {
    alert("*******Success*********");
    var response=JSON.stringify(data);
    alert("success="+response);
    document.getElementById("employeeDetails").value=response;
});

5

หากคุณใช้ express คุณสามารถใช้ cors middleware ดังนี้:

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

3

เพิ่มสิ่งนี้ไปยังเซิร์ฟเวอร์ NodeJS ของคุณด้านล่างการนำเข้า:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

3

หากคุณมี 403 หลังจากนั้นโปรดลดตัวกรองใน WEB.XML tomcat config ดังต่อไปนี้:

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
</filter>

2

ในที่สุดฉันก็ได้รับคำตอบสำหรับ apache Tomcat8

คุณต้องแก้ไขไฟล์ tomcat web.xml

น่าจะเป็นในโฟลเดอร์ webapps

sudo gedit /opt/tomcat/webapps/your_directory/WEB-INF/web.xml

ค้นหาและแก้ไข

<web-app>


<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
  <init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
  </init-param>
</filter>


<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>



</web-app>

สิ่งนี้จะทำให้ Access-Control-Allow-Origin เป็นโฮสต์ทั้งหมด หากคุณต้องการเปลี่ยนจากโฮสต์ทั้งหมดเป็นเฉพาะโฮสต์ของคุณคุณสามารถแก้ไข

<param-name>cors.allowed.origins</param-name>
<param-value>http://localhost:3000</param-value>

โค้ดด้านบนจาก * เป็นhttp: // your_public_IPหรือ http://www.example.com ของคุณ

คุณสามารถอ่านเอกสารตัวกรอง Tomcat ได้ที่นี่

ขอบคุณ


1

สวัสดีนี่เป็นวิธีการแก้ปัญหา CORS ในโหนดเพียงเพิ่มบรรทัดเหล่านี้บนเซิร์ฟเวอร์ "api" ด้านใน Node.js (หรือไฟล์เซิร์ฟเวอร์ของคุณเคย), ก่อนที่จะติดตั้ง "cors"

    const express = require('express');
    const app = express();
    app.use(express.json());
    var cors = require('cors');
    app.use(cors());

0

ใช้ dataType: 'jsonp' ใช้งานได้สำหรับฉัน

   async function get_ajax_data(){

       var _reprojected_lat_lng = await $.ajax({

                                type: 'GET',

                                dataType: 'jsonp',

                                data: {},

                                url: _reprojection_url,

                                error: function (jqXHR, textStatus, errorThrown) {

                                    console.log(jqXHR)

                                },

                                success: function (data) {

                                    console.log(data);



                                    // note: data is already json type, you just specify dataType: jsonp

                                    return data;

                                }

                            });





 } // function               

0

สำหรับ PHP ใช้เพื่อตั้งค่าส่วนหัว

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT, GET, POST");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");

0
router.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers", "*");
next();});

เพิ่มไปยังเส้นทางของคุณที่คุณโทรจาก front-end ตัวอย่างเช่นถ้าคุณโทรหาhttp: // localhost: 3000 / users / registerคุณจะต้องเพิ่มส่วนของรหัสนี้ลงในไฟล์ back-end .js ที่เส้นทางนี้วาง


0

ในกรณีที่ใครก็ตามที่ค้นหาวิธีแก้ปัญหาถ้าคุณใช้ express ที่นี่เป็นวิธีแก้ปัญหาอย่างรวดเร็ว

const express = require('express')
const cors = require('cors')
const app = express()

1) ติดตั้ง cors โดยใช้ npm npm install cors --save

2) นำเข้า [ต้องการ] const cors = require('cors')

3) ใช้เป็นตัวกลาง app.use(cors())

สำหรับรายละเอียดinsatll และการใช้งานของล ธ หวังว่ามันจะใช้ได้


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