Pochodzenie <origin> nie jest dozwolone przez 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. 

Czytałem o zapytaniach AJAX między domenami i rozumiem podstawowy problem z bezpieczeństwem. W moim przypadku 2 serwery działają lokalnie i lubią włączać żądania międzydomenowe podczas testowania.

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

Wystawiam żądanie AJAX do, localhost:8080 - GAE servergdy moja strona jest ładowana z serwera węzła. Co jest najłatwiejsze i najbezpieczniejsze (nie chcę uruchamiać chrome z disable-web-securityopcją). Jeśli muszę zmienić 'Content-Type', czy powinienem to zrobić na serwerze węzła? W jaki sposób?


Szybsze rozwiązanie można znaleźć tutaj: stackoverflow.com/a/21622564/4455570
— Gabriel Wamunyu

Odpowiedzi:


195

Ponieważ działają na różnych portach, są to różne JavaScript origin. Nie ma znaczenia, że ​​są na tej samej maszynie / nazwie hosta.

Musisz włączyć CORS na serwerze (localhost: 8080). Sprawdź tę witrynę: http://enable-cors.org/

Wszystko, co musisz zrobić, to dodać nagłówek HTTP do serwera:

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

Lub dla uproszczenia:

Access-Control-Allow-Origin: *

Nie należy używać znaku „*”, jeśli serwer próbuje ustawić plik cookie, a Ty używasz withCredentials = true

odpowiadając na żądanie poświadczone, serwer musi określić domenę i nie może używać symboli wieloznacznych.

Możesz przeczytać więcej o tym withCredentialstutaj


jeśli chcemy dodać ten nagłówek do kodu HTML, co powinniśmy z tym zrobić?
— Azam Alvi

1
Nie sądziłem, że ten port jest konieczny, ale jeśli używasz niestandardowego portu, takiego jak 3000, musisz uwzględnić go w zasadach CORS.
— Michael Connor

4
Dzięki za tę odpowiedź. Chcę tylko podkreślić implikacje bezpieczeństwa wynikające z użycia „*” jako wartości tutaj. To pozwala wszystkim źródłom: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ ... Wygląda na to, że pierwszy przykład byłby najlepszy pod względem najmniejszego dostępu. Szczegółowe informacje o tym, jak to zrobić z wieloma domenami, znajdziesz tutaj: stackoverflow.com/a/1850482/1566623
— Christopher Kuttruff

14
Dla jasności, kiedy mówi się, że trzeba „dodać nagłówek HTTP do serwera”, oznacza to, że dany Access-Control-Allow-Originnagłówek musi być nagłówkiem dodanym do odpowiedzi HTTP wysyłanych przez serwer. Ten nagłówek musi być częścią odpowiedzi serwera, nie musi być częścią żądania klienta . W szczególności dzieje się, zanim klient wyśle ​​żądane żądanie , przeglądarka wysyła OPTIONSżądanie przed nim, a jeśli odpowiedź serwera na to OPTIONSżądanie nie zawiera nagłówka, przeglądarka nie wyśle ​​żądanego żądania.
— AjaxLeung

1
Ważne jest, aby przeczytać odpowiednie wskazówki dotyczące serwerów zaplecza na stronie enable-cors.org.
— Karlth

69

Jeśli potrzebujesz szybkiego obejścia w Chrome dla żądań Ajax, ta wtyczka Chrome automatycznie umożliwia dostęp do dowolnej witryny z dowolnego źródła, dodając odpowiedni nagłówek odpowiedzi

Rozszerzenie Chrome Allow-Control-Allow-Origin: *


6
Nie wiem, dlaczego nie dostajesz więcej pozytywnych głosów. Jest to najmniej uciążliwe dla programowania na hoście lokalnym z Chrome.
— David Betz

zdecydowanie się zgadzam. Łatwe do włączenia dla deweloperów localhost na zdalnym serwerze bez konieczności zmiany konfiguracji zdalnego serwera.
— Jens Wegar

@DavidBetz: biorąc pod uwagę, że zweryfikujesz rozszerzenie i ufasz mu, oczywiście;)
— haylem

2
TO POWINNO BYĆ NAJLEPSZA ODPOWIEDŹ! Zwłaszcza jeśli chodzi o localhost.
— Pan Benedict,

16
Gdyby to było dobre rozwiązanie, nie zostałby wynaleziony CORS. Zastosowanie tego nagłówka do dowolnego hosta wyłącza ochronę CORS i naraża cię na złośliwe skrypty, nie tylko twoje. Nie zdziw się, jeśli Twoje konto bankowe nagle się opróżni.
— dolmen

54

Musisz włączyć CORS, aby rozwiązać ten problem

jeśli Twoja aplikacja została utworzona za pomocą prostego node.js.

ustaw go w nagłówkach odpowiedzi, takich jak

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

jeśli Twoja aplikacja została utworzona w ramach ekspresowej platformy

użyj oprogramowania pośredniczącego CORS, takiego jak

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

i aplikuj przez

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

Oto dwa linki referencyjne

  1. jak zezwolić-cors-in-express-nodejs
  2. nurkowanie w node-js-very-first-app # zobacz sekcję Ajax

czy możesz określić, jak używać config.allowedDomains. powiedz w moim przypadku, jakie URI mam tam umieścić?
— bsr,

@bsr: możesz użyć *lub, do specific domainktórego chcesz przyznać dostęp.
— mithunsatheesh,

1
więc czy tylko ja otrzymuję app.configure()to nie błąd funkcji?
— Pramesh Bajracharya

@PrameshBajrachaya Nie załączyłem „app.configure” part - only „app.use (allowCrossDomain)” i to zadziałało.
— Giorgos Sfikas

8

Akceptuję odpowiedź @Rocket Hazmat, która prowadzi mnie do rozwiązania. Rzeczywiście musiałem ustawić nagłówek na serwerze GAE. Musiałem to ustawić

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

ustawienie "Access-Control-Allow-Origin" dawało tylko błąd

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

Ponadto, jeśli trzeba wysłać token uwierzytelniania, dodaj to również

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

Również u klienta ustawione withCredentials

powoduje to wysłanie 2 żądań do serwera, w tym jednego z OPTIONS. Plik cookie uwierzytelniający nie jest wysyłany wraz z nim, dlatego należy traktować uwierzytelnianie zewnętrzne.


7

W routerze.js po prostu dodaj kod przed wywołaniem metod get / post. U mnie działa bezbłędnie.

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

Miałem problem podczas wywoływania zasobów pochodzących z innych źródeł przy użyciu AJAX z Chrome.

Użyłem node js i lokalnego serwera http do wdrożenia mojej aplikacji node js.

Otrzymałem odpowiedź o błędzie podczas uzyskiwania dostępu do zasobu między źródłami

Znalazłem na to jedno rozwiązanie,

1) Dodałem poniższy kod do mojego pliku app.js.

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

2) Na mojej stronie html o nazwie cross-origin resource using $.getJSON();

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

5

Jeśli korzystasz z usługi Express, możesz użyć oprogramowania pośredniego cors w następujący sposób:

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

app.use(cors())

3

Dodaj to do swojego serwera NodeJS poniżej importu:

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

Jeśli po tym otrzymałeś 403, zredukuj filtry w konfiguracji tomcat WEB.XML do następującego:

<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

W końcu dostałem odpowiedź na apache Tomcat8

Musisz edytować plik tomcat web.xml.

prawdopodobnie będzie w folderze webapps,

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

znajdź go i edytuj

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

Umożliwi to dostęp-kontrolę-zezwolenie-pochodzenia wszystkim hostom. Jeśli chcesz zmienić go ze wszystkich hostów na tylko swój host, możesz edytować plik

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

powyższy kod od * do adresu http: // your_public_IP lub http://www.example.com

możesz odwołać się tutaj dokumentacji filtra Tomcat

Dzięki


1

Cześć To jest sposób na rozwiązanie problemu CORS w węźle Po prostu dodaj te linie po stronie "api" serwera w Node.js (lub jakimkolwiek pliku serwera), zanim to upewnij się, że zainstalowałeś "cors"

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

0

użyj typu dataType: „jsonp”, działa dla mnie.

   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

W przypadku PHP użyj tego do ustawienia nagłówków.

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

dodaj to do swoich tras, do których dzwonisz z front-endu. Np. Jeśli wywołujesz http: // localhost: 3000 / users / register , musisz dodać ten fragment kodu do pliku .js zaplecza, który tworzy ta trasa.


0

Jeśli ktoś szuka rozwiązania, jeśli korzystasz z ekspresu, to szybkie rozwiązanie.

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

1) zainstaluj przewody za pomocą npm npm install cors --save

2) zaimportuj [wymagaj] const cors = require('cors')

3) używać go jako oprogramowania pośredniego app.use(cors())

aby uzyskać szczegółowe informacje, wstaw i zastosowanie cors . To jest to, mam nadzieję, że działa.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.