Não ‘Access-Control-Allow-Origin’ – problema de porta do nó / Apache

Eu criei uma pequena API usando o Node / Express e tentando puxar dados usando Angularjs, mas como a minha página html está sendo executado sob apache no localhost: 8888 e nó API está escutando na porta 3000, estou recebendo o No ‘Access-Control- Permitir-Origem ‘. Eu tentei usar node-http-proxy e Vhosts Apache, mas não tendo muito sucesso, por favor, veja o erro completo e código abaixo.

“XMLHttpRequest não pode carregar localhost: 3000. Nenhum header ‘Access-Control-Allow-Origin’ está presente no recurso solicitado. A origem ‘localhost: 8888’ não tem, portanto, access.”

// 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') // Angular code angular.module('contractorsApp', []) .controller('ContractorsCtrl', function($scope, $http,$routeParams) { $http.get('localhost:3000').success(function(data) { $scope.contractors = data; }) // HTML  
  • {{person.name}}

Tente adicionar o seguinte middleware ao seu aplicativo NodeJS / Express (adicionei alguns comentários para sua conveniência):

 // 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 (eg in case you use sessions) res.setHeader('Access-Control-Allow-Credentials', true); // Pass to next layer of middleware next(); }); 

Espero que ajude!

Resposta aceita é bom, no caso de você preferir algo mais curto, você pode usar um plugin chamado cors disponível para Express.js

É simples de usar, neste caso particular:

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

Outra maneira é simplesmente adicionar os headers ao seu trajeto:

 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:)'); }); 

A resposta principal funcionou bem para mim, exceto que eu precisava colocar mais de um domínio na lista de permissions.

Além disso, a resposta principal sofre do fato de que a solicitação OPTIONS não é tratada pelo middleware e você não a obtém automaticamente.

Eu armazeno domínios na lista de permissions como allowed_origins na configuração Express e coloco o domínio correto de acordo com o header de origin já que o Access-Control-Allow-Origin não permite especificar mais de um domínio.

Aqui está o que acabei com:

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

O código de resposta permite somente ao localhost: 8888. Esse código não pode ser implementado na produção ou em um servidor e nome de porta diferentes.

Para que funcione para todas as fonts, use isto:

 // 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 (eg in case you use sessions) res.setHeader('Access-Control-Allow-Credentials', true); // Pass to next layer of middleware next(); }); 
 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(); } }); 

Você pode usar “$ http.jsonp”

OU

Abaixo está a solução para o chrome para testes locais

Você precisa abrir o seu cromo com o seguinte comando. (Pressione a janela + R)

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

Nota: o seu cromo não deve estar aberto. Quando você executar este comando, o chrome será aberto automaticamente.

Se você estiver digitando este comando no prompt de comando, selecione seu diretório de instalação do chrome e use este comando.

Abaixo do código de script para chrome aberto no MAC com “–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 &" 

segundas opções

Você pode simplesmente usar o open (1) para adicionar os sinalizadores: open -a ‘Google Chrome’ –args –allow-file-access-from-files

 /** * 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. 
 //Add following code in app.js of NODEJ Restful api to avoid "Access-Control-Allow-Origin" error in angular 6 or any other 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 })); 

Instale a dependência de cors em seu projeto:

 npm i --save cors 

Adicione ao seu arquivo de configuração do servidor o seguinte:

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

Funciona para mim com a versão 2.8.4 cors.