Sin 'Access-Control-Allow-Origin' - Problema con el puerto de nodo/Apache

Resuelto user1336103 asked hace 11 años • 17 respuestas

Creé una pequeña API usando Node/Express e intenté extraer datos usando Angularjs, pero como mi página html se ejecuta en Apache en localhost:8888 y la API del nodo escucha en el puerto 3000, obtengo el mensaje No 'Access-Control- Permitir origen'. Intenté usar node-http-proxyVhosts Apache pero no tuve mucho éxito; consulte el error completo y el código a continuación.

XMLHttpRequest no puede cargar localhost:3000. No hay ningún encabezado 'Access-Control-Allow-Origin' en el recurso solicitado. Por lo tanto, no se permite el acceso al origen 'localhost:8888'.

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

código angular

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>
user1336103 avatar Aug 19 '13 16:08 user1336103
Aceptado

Intente agregar el siguiente middleware a su aplicación NodeJS/Express (he agregado algunos comentarios para su conveniencia):

// Add headers before the routes are defined
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();
});

(Es posible que necesites utilizar 127.0.0.1en lugar de localhost.)

jvandemo avatar Aug 19 '2013 10:08 jvandemo

La respuesta aceptada está bien, en caso de que prefiera algo más corto, puede usar un complemento llamado cors disponible para Express.js.

Es simple de usar, para este caso particular:

var cors = require('cors');

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

(Es posible que necesites utilizar 127.0.0.1en lugar de localhost.)

El origen de la solicitud debe coincidir con los orígenes permitidos y también puede tener varios de ellos:

app.use(
  cors({origin: ['http://localhost:8888', 'http://127.0.0.1:8888']})
);
Fabiano Soriani avatar Dec 18 '2015 00:12 Fabiano Soriani

Otra forma es simplemente agregar los encabezados a su ruta:

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:)');
});
Asaf Hananel avatar Nov 26 '2016 16:11 Asaf Hananel