Nguồn gốc <origin> không được phép bởi Access-Control-Allow-Origin


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

Tôi đọc về các yêu cầu ajax tên miền chéo và hiểu vấn đề bảo mật cơ bản. Trong trường hợp của tôi, 2 máy chủ đang chạy cục bộ và muốn bật các yêu cầu tên miền chéo trong quá trình thử nghiệm.

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

Tôi đang đưa ra yêu cầu ajax localhost:8080 - GAE servertrong khi trang của tôi được tải từ máy chủ nút. Cái gì là dễ nhất và an toàn nhất (Đừng muốn bắt đầu chrome với disable-web-securitytùy chọn). Nếu tôi phải thay đổi 'Content-Type', tôi có nên làm điều đó tại máy chủ nút không? Làm sao?


Một giải pháp nhanh hơn có thể được tìm thấy ở đây: stackoverflow.com/a/21622564/4455570
Gabriel Wamunyu

Câu trả lời:


194

Vì chúng đang chạy trên các cổng khác nhau, chúng là JavaScript khác nhau origin. Việc họ ở trên cùng một máy / tên máy chủ không thành vấn đề.

Bạn cần kích hoạt CORS trên máy chủ (localhost: 8080). Kiểm tra trang web này: http://enable-cors.org/

Tất cả những gì bạn cần làm là thêm một tiêu đề HTTP vào máy chủ:

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

Hoặc, để đơn giản:

Access-Control-Allow-Origin: *

Thiết nghĩ không sử dụng "*" nếu máy chủ của bạn đang cố gắng đặt cookie và bạn sử dụng withCredentials = true

khi trả lời yêu cầu được xác thực, máy chủ phải chỉ định tên miền và không thể sử dụng thẻ hoang dã.

Bạn có thể đọc thêm về withCredentialsđây


Nếu chúng ta muốn thêm tiêu đề này vào HTML thì chúng ta phải làm gì cho nó?
Azam Alvi

1
Tôi không nghĩ rằng cổng đó là cần thiết nhưng nếu bạn đang sử dụng một cổng không chuẩn như 3000 thì bạn phải đưa nó vào chính sách CORS.
Michael Connor

4
Cảm ơn phản hồi này. Chỉ muốn làm nổi bật ý nghĩa bảo mật của việc sử dụng '*' làm giá trị ở đây. Điều này cho phép tất cả các nguồn gốc: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ gợi Có vẻ như ví dụ đầu tiên sẽ tốt nhất về mặt ít truy cập nhất. Chi tiết về cách thực hiện việc này với nhiều tên miền tại đây: stackoverflow.com/a/1850482/1566623
Christopher Kuttruff

14
Để rõ ràng, khi người ta nói rằng bạn cần "thêm tiêu đề HTTP vào máy chủ", điều này có nghĩa là Access-Control-Allow-Origintiêu đề đã cho cần phải là một tiêu đề được thêm vào phản hồi HTTP mà máy chủ gửi. Tiêu đề này cần phải là một phần của phản hồi của máy chủ, nó không cần phải là một phần trong yêu cầu của khách hàng . Cụ thể những gì xảy ra là trước khi máy khách thực hiện yêu cầu thực tế mà bạn muốn, trình duyệt sẽ gửi OPTIONSyêu cầu trước yêu cầu đó và nếu phản hồi của máy chủ đối với OPTIONSyêu cầu đó không chứa tiêu đề, trình duyệt sẽ không gửi yêu cầu bạn muốn.
AjaxLeung

1
Điều quan trọng là phải đọc các mẹo có liên quan cho các máy chủ phụ trợ của bạn tại enable-cors.org.
Thứ ba

69

Nếu bạn cần một công việc nhanh chóng trong Chrome cho các yêu cầu ajax, plugin chrome này tự động cho phép bạn truy cập bất kỳ trang web nào từ bất kỳ nguồn nào bằng cách thêm tiêu đề phản hồi phù hợp

Tiện ích mở rộng cho phép kiểm soát-cho phép-xuất xứ của Chrome: *


6
Tôi không biết tại sao bạn không nhận được nhiều hơn. Đây là cách xâm nhập ít nhất để phát triển trên localhost với Chrome.
David Betz

hoàn toàn đồng ý. Dễ dàng kích hoạt cho localhost dev đối với máy chủ từ xa mà không phải thay đổi cấu hình cho máy chủ từ xa.
Jens Wegar

@DavidBetz: tất nhiên là xem xét bạn xác minh tiện ích mở rộng và tin tưởng vào nó;)
haylem

2
NÀY NÊN LÀ TRẢ LỜI HÀNG ĐẦU! Đặc biệt là nơi localhost có liên quan.
Ông Benedict

16
Nếu đây là một giải pháp tốt, CORS sẽ không được phát minh ngay từ đầu. Áp dụng tiêu đề này cho bất kỳ máy chủ nào sẽ vô hiệu hóa bảo vệ CORS và đưa bạn đến các tập lệnh độc hại, không chỉ của bạn. Đừng ngạc nhiên nếu tài khoản ngân hàng của bạn đột nhiên trống rỗng.
heo

54

Bạn phải kích hoạt CORS để giải quyết điều này

nếu ứng dụng của bạn được tạo bằng node.js đơn giản

đặt nó trong tiêu đề phản hồi của bạn như

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);

nếu ứng dụng của bạn được tạo với khung thể hiện

sử dụng phần mềm trung gian CORS như

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();
}

và áp dụng thông qua

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

Đây là hai liên kết tham khảo

  1. how-to-allow-cors-in-express-nodejs
  2. lặn-vào-nút-js-rất-ứng dụng đầu tiên # xem phần Ajax

bạn có thể vui lòng chỉ định, làm thế nào để sử dụng config.allowedDomains. Nói trong trường hợp của tôi những gì tôi nên đặt ở đó?
bsr

@bsr: bạn có thể sử dụng *hoặc specific domainbạn muốn cấp quyền truy cập.
mithuneditesh

1
Vì vậy, tôi là người duy nhất nhận app.configure()được không phải là một lỗi chức năng?
Pramesh Bajracharya

@PrameshBajrachaya Tôi không bao gồm phần "app.configure" - chỉ "app.use (allowCrossDomain)" và nó hoạt động với tôi.
Giorgos Sfikas

8

Tôi chấp nhận câu trả lời của @Rocket hazmat vì nó dẫn tôi đến giải pháp. Đó thực sự là trên máy chủ GAE tôi cần để đặt tiêu đề. Tôi phải đặt những thứ này

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

cài đặt chỉ "Access-Control-Allow-Origin" đưa ra lỗi

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

Ngoài ra, nếu mã thông báo xác thực cần được gửi, hãy thêm mã này

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

Ngoài ra, tại máy khách, thiết lập withCredentials

Điều này gây ra 2 yêu cầu được gửi đến máy chủ, một yêu cầu OPTIONS. Auth cookie không được gửi cùng với nó, do đó cần phải xử lý bên ngoài auth.


7

Trong router.js chỉ cần thêm mã trước khi gọi phương thức get / post. Nó hoạt động cho tôi mà không có lỗi.

//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

Tôi đã phải đối mặt với một vấn đề trong khi gọi tài nguyên nguồn gốc chéo bằng cách sử dụng ajax từ chrome.

Tôi đã sử dụng nút js và máy chủ http cục bộ để triển khai ứng dụng js nút của mình.

Tôi đã nhận được phản hồi lỗi, khi tôi truy cập tài nguyên nguồn gốc chéo

Tôi tìm thấy một giải pháp về điều đó,

1) Tôi đã thêm mã dưới đây vào tệp app.js của mình

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

2) Trong trang html của tôi được gọi là tài nguyên nguồn gốc chéo bằng cách sử dụng $.getJSON();

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

5

Nếu bạn đang sử dụng express, bạn có thể sử dụng phần mềm trung gian cors như sau:

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

app.use(cors())

3

Thêm phần này vào Máy chủ NodeJS của bạn bên dưới nhập:

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

Nếu bạn có 403 sau đó, vui lòng giảm các bộ lọc trong cấu hình tomcat WEB.XML xuống như sau:

<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

Cuối cùng tôi đã có câu trả lời cho apache Tomcat8

Bạn phải chỉnh sửa tệp webcat tomcat.

chắc chắn nó sẽ nằm trong thư mục webapps,

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

tìm nó và chỉnh sửa nó

<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>

Điều này sẽ cho phép Access-Control-Cho phép-Origin tất cả các máy chủ. Nếu bạn cần thay đổi nó từ tất cả các máy chủ thành chỉ máy chủ của bạn, bạn có thể chỉnh sửa

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

mã ở trên từ * đến http: // your_public_IP của bạn hoặc http://www.example.com của bạn

bạn có thể tham khảo tài liệu bộ lọc Tomcat

Cảm ơn


1

Xin chào Đây là cách để giải quyết vấn đề CORS trong nút Chỉ cần thêm các dòng này ở phía "api" của máy chủ trong Node.js (hoặc bất cứ khi nào Tệp máy chủ của bạn), hãy đảm bảo cài đặt "cors"

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

0

sử dụng dataType: 'jsonp', hoạt động với tôi.

   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

Đối với PHP, sử dụng điều này để đặt tiêu đề.

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();});

thêm phần này vào các tuyến mà bạn đang gọi từ front-end. Ví dụ: nếu bạn gọi cho http: // localhost: 3000 / users / đăng ký, bạn phải thêm đoạn mã này vào tệp .js back-end mà tuyến này đặt.


0

Trong trường hợp bất cứ ai tìm kiếm giải pháp, nếu bạn đang sử dụng express ở đây là giải pháp nhanh chóng.

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

1) cài đặt cors bằng npm npm install cors --save

2) nhập nó [yêu cầu] const cors = require('cors')

3) sử dụng nó như là phần mềm trung gian app.use(cors())

để biết chi tiết và sử dụng cors . Đó là nó, hy vọng nó hoạt động.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.