No 'Access-Control-Allow-Origin' - Problema alla porta Node / Apache


260

ho creato una piccola API usando Node / Express e cercando di estrarre i dati usando Angularjs ma poiché la mia pagina html è in esecuzione sotto apache su localhost: 8888 e l'API del nodo è in ascolto sulla porta 3000, sto ottenendo il No 'Access-Control- consentire-Origin'. Ho provato a utilizzare node-http-proxye Vhosts Apache ma non riscuote molto successo, vedere l'errore e il codice completi di seguito.

XMLHttpRequest non può caricare localhost: 3000. Nessuna intestazione "Access-Control-Allow-Origin" è presente sulla risorsa richiesta. Pertanto, "localhost: 8888" non può accedere. "

// Api Using Node/Express    
var express = require('express');
var app = express();
var contractors = [
    {   
     "id": "1", 
        "name": "Joe Blogg",
        "Weeks": 3,
        "Photo": "1.png"
    }
];

app.use(express.bodyParser());

app.get('/', function(req, res) {
  res.json(contractors);
});
app.listen(process.env.PORT || 3000);
console.log('Server is running on Port 3000')

Codice angolare

angular.module('contractorsApp', [])
.controller('ContractorsCtrl', function($scope, $http,$routeParams) {

   $http.get('localhost:3000').then(function(response) {
       var data = response.data;
       $scope.contractors = data;
   })

HTML

<body ng-app="contractorsApp">
    <div ng-controller="ContractorsCtrl"> 
        <ul>
            <li ng-repeat="person in contractors">{{person.name}}</li>
        </ul>
    </div>
</body>

Risposte:


622

Prova ad aggiungere il seguente middleware alla tua app NodeJS / Express (ho aggiunto alcuni commenti per comodità):

// Add headers
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

Spero che aiuti!


2
Potete aiutarmi a specificare esattamente dove va? Ho il seguente codice nel mio server. Va bene dopo questo? var app = request ('express') (), server = Require ('http'). createServer (app), io = Require ('socket.io'). hear (server), request = Require ("richiesta") , url = request ("url"); server.listen (6969); // va qui? su una nuova linea?
Art Geigel,

1
@jvandemo devo cambiare l'app.get ('/', funzione (req, res) in ... funzione (req, res, next)?
Sangram Singh

10
Sei la mia persona preferita in assoluto in questo momento. Grazie. Possiamo aggiungere una nota che questo codice deve avvenire prima che vengano definite le rotte per nessuno come me?
gegillam,

1
Come farlo funzionare mentre si utilizza il modulo di richiesta?
Rohit Tigga,

2
Non ha funzionato nel mio caso. Sempre visualizzato questo errore: "La risposta alla richiesta di verifica preliminare non supera il controllo del controllo di accesso: non è presente alcuna intestazione" Access-Control-Allow-Origin "sulla risorsa richiesta. L'origine" abc.xyz.net:212 "non è pertanto consentita accesso. La risposta aveva il codice di stato HTTP 500. "
user1451111,

96

La risposta accettata va bene, nel caso in cui preferisci qualcosa di più corto, puoi usare un plugin chiamato cors disponibile per Express.js

È semplice da usare, per questo caso particolare:

var cors = require('cors');

// use it before all route definitions
app.use(cors({origin: 'http://localhost:8888'}));

3
Ho dovuto usarlo {origin: 'null'}per funzionare ... Apparentemente, il mio browser invia nullcome origine?
Ricardo Cruz,

2
Perché reinventare la ruota. Sono sempre alla ricerca di una soluzione pacchettizzata rispetto allo snippet di codice
Pierre

dolce piccola biblioteca che ha gestito il mio caso d'uso di volere metodi diversi da origini diverse abbastanza bene ... e meno fatica del codice per il prossimo ragazzo che lo guarda.
Kyle Baker,

6
Grazie, ha app.use(cors({origin: '*'}));funzionato per me, come da enable-cors .
danialk,

2
Suggerisco di dare un'occhiata alla pagina cors npm per sfruttarla al meglio. Ha reso le cose molto chiare per me =).
13013SwagR

30

Un altro modo è semplicemente aggiungere le intestazioni al percorso:

router.get('/', function(req, res) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // If needed
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // If needed
    res.setHeader('Access-Control-Allow-Credentials', true); // If needed

    res.send('cors problem fixed:)');
});

8
)di smiley mi ha confuso
Eco Eco

17

La risposta migliore ha funzionato bene per me, tranne per il fatto che dovevo inserire nella whitelist più di un dominio.

Inoltre, la risposta migliore risente del fatto che la OPTIONSrichiesta non viene gestita dal middleware e non la si ottiene automaticamente.

Conservo i domini autorizzati come allowed_originsnella configurazione Express e inserisco il dominio corretto in base all'intestazione originpoiché Access-Control-Allow-Originnon consente di specificare più di un dominio.

Ecco cosa ho finito con:

var _ = require('underscore');

function allowCrossDomain(req, res, next) {
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');

  var origin = req.headers.origin;
  if (_.contains(app.get('allowed_origins'), origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }

  if (req.method === 'OPTIONS') {
    res.send(200);
  } else {
    next();
  }
}

app.configure(function () {
  app.use(express.logger());
  app.use(express.bodyParser());
  app.use(allowCrossDomain);
});

È lo stesso "if (app.get (" origini consentite "). IndexOf (origine)! == - 1)?"?
Rune Jeppesen,

13

Il codice di risposta consente solo a localhost: 8888. Questo codice non può essere distribuito alla produzione o al nome del server e della porta diversi.

Per farlo funzionare per tutte le fonti, utilizzare questo invece:

// Add headers
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', '*');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

2
Questo non funziona per me! "* non è un'origine valida". Sembra che il carattere * non sia riconosciuto come carattere jolly.
Francesco,

Per me funziona. cioè usando il carattere jolly '*'. funziona sia per Chrome che per Safari.
AnBisw,

Grazie;) Funziona bene
Mauro,

9

Installa cors depend nel tuo progetto:

npm i --save cors

Aggiungere al file di configurazione del server quanto segue:

var cors = require('cors');
app.use(cors());

Funziona per me con la versione 2.8.4 cors.


"cors": "^2.8.5", "express": "^4.16.3",funziona bene solo con la linea suggerita da @monikaja. Grazie!
RamiroIsBack

Ciò consente di consentire a tutte le origini / domini di accedere all'app, cosa che di solito non si desidera fare. Invece specifica solo i domini consentiti.
Lacho Tomov,

7

Questo ha funzionato per me.

app.get('/', function (req, res) {

    res.header("Access-Control-Allow-Origin", "*");
    res.send('hello world')
})

Puoi cambiare * per soddisfare le tue esigenze. Spero che questo possa aiutare.


7

Salve, questo accade quando il front-end e il back-end sono in esecuzione su porte diverse. Il browser blocca le risposte dal back-end a causa dell'assenza nelle intestazioni CORS. La soluzione consiste nell'aggiungere le intestazioni CORS nella richiesta di backend. Il modo più semplice è usare il pacchetto cors npm.

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

Ciò abiliterà le intestazioni CORS in tutte le vostre richieste. Per ulteriori informazioni, consultare la documentazione cors

https://www.npmjs.com/package/cors


3
app.all('*', function(req, res,next) {
    /**
     * Response settings
     * @type {Object}
     */
    var responseSettings = {
        "AccessControlAllowOrigin": req.headers.origin,
        "AccessControlAllowHeaders": "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5,  Date, X-Api-Version, X-File-Name",
        "AccessControlAllowMethods": "POST, GET, PUT, DELETE, OPTIONS",
        "AccessControlAllowCredentials": true
    };

    /**
     * Headers
     */
    res.header("Access-Control-Allow-Credentials", responseSettings.AccessControlAllowCredentials);
    res.header("Access-Control-Allow-Origin",  responseSettings.AccessControlAllowOrigin);
    res.header("Access-Control-Allow-Headers", (req.headers['access-control-request-headers']) ? req.headers['access-control-request-headers'] : "x-requested-with");
    res.header("Access-Control-Allow-Methods", (req.headers['access-control-request-method']) ? req.headers['access-control-request-method'] : responseSettings.AccessControlAllowMethods);

    if ('OPTIONS' == req.method) {
        res.send(200);
    }
    else {
        next();
    }


});

2

Aggiungi il seguente codice in app.js di NODEJ API riposanti per evitare l'errore "Access-Control-Allow-Origin" nell'angolo 6 o in qualsiasi altro framework

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

var cors = require('cors');
var bodyParser = require('body-parser');

//enables cors
app.use(cors({
  'allowedHeaders': ['sessionId', 'Content-Type'],
  'exposedHeaders': ['sessionId'],
  'origin': '*',
  'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
  'preflightContinue': false
}));

1

Puoi usare "$ http.jsonp"

O

Di seguito è riportato il lavoro per Chrome per i test locali

Devi aprire Chrome con il seguente comando. (Premi finestra + R)

Chrome.exe --allow-file-access-from-files

Nota: Chrome non deve essere aperto. Quando esegui questo comando chrome si aprirà automaticamente.

Se si immette questo comando nel prompt dei comandi, selezionare la directory di installazione di Chrome quindi utilizzare questo comando.

Sotto il codice dello script per open chrome in MAC con "--allow-file-access-from-files"

set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" 
set switch to " --allow-file-access-from-files"
do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"

seconde opzioni

Puoi semplicemente usare open (1) per aggiungere i flag: open -a 'Google Chrome' --args --allow-file-access-from-files


Che ne dici di MAC ?? Chrome.exe --allow-file-access-from-files
user1336103

/ Applicazioni / Google \ Chrome.app/Contents/MacOS/Google \ Chrome --allow-file-access-from-files riesce ad aprire Chrome ma il messaggio mostra ancora "XMLHttpRequest non può caricare localhost: 3000. Origin localhost: 8888 è non consentito da Access-Control-Allow-Origin. "
user1336103

+1 Posso confermare che funziona con l'opzione Mac usando 'apri'. Il mio caso è un po 'diverso in quanto sto semplicemente testando un sito completamente scaricato che accede ad alcuni file JSON locali.
spong

0

/**
 * Allow cross origin to access our /public directory from any site.
 * Make sure this header option is defined before defining of static path to /public directory
 */
expressApp.use('/public',function(req, res, next) {
    res.setHeader("Access-Control-Allow-Origin", "*");
    // Request headers you wish to allow
    res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    // Set to true if you need the website to include cookies in the requests sent
    res.setHeader('Access-Control-Allow-Credentials', true);
    // Pass to next layer of middleware
    next();
});


/**
 * Server is about set up. Now track for css/js/images request from the 
 * browser directly. Send static resources from "./public" directory. 
 */
expressApp.use('/public', express.static(path.join(__dirname, 'public')));
If you want to set Access-Control-Allow-Origin to a specific static directory you can set the following.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.