Нет Проблемы С Портом "Access-Control-Allow-Origin" - Node / Apache

Я создал небольшой API, используя Node / Express и пытаясь вытащить данные с помощью Angularjs, но поскольку моя html-страница работает под apache на localhost:8888 и Node API прослушивает порт 3000, я получаю No 'Access-Control-Allow-Origin'. Я попытался использовать node-http-proxy и Vhosts Apache, но не имея больших успехов, см. полную ошибку и код ниже.

" XMLHttpRequest не может загрузить localhost: 3000. Заголовок "Access-Control-Allow-Origin" отсутствует в запрошенном заголовке ресурс. Поэтому Origin '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')


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

   $http.get('localhost:3000').success(function(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>

10 ответов


попробуйте добавить следующее промежуточное ПО в приложение NodeJS/Express (я добавил несколько комментариев для вашего удобства):

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

надеюсь, что это поможет!


принятый ответ в порядке, если вы предпочитаете что-то короче, вы можете использовать плагин под названием cors доступно для Express.js

Он прост в использовании, для этого конкретного случая:

var cors = require('cors');

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

другой способ, просто добавить заголовки к вашему маршруту:

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

на лучшие ответы работал отлично для меня, за исключением того, что мне нужно было белый список более одного домена.

кроме того, верхний ответ страдает от того, что OPTIONS запрос не обрабатывается промежуточным программным обеспечением, и вы не получаете его автоматически.

я храню белый список доменов как allowed_origins в экспресс-конфигурации и поставить правильный домен в соответствии с С Access-Control-Allow-Origin не позволяет указать более одного домена.

вот что я в итоге:

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

код ответа позволяет только localhost: 8888. Этот код не может быть развернут на производстве или на другом сервере и имени порта.

чтобы заставить его работать для всех источников, используйте этот код:

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

установите зависимость cors в свой проект:

npm i --save cors

добавьте в файл конфигурации сервера следующее:

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

он работает для меня с версией 2.8.4 cors.


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


});

вы можете использовать " $http.JSONP в"

или

Ниже приведена работа для chrome для локального тестирования

вам нужно открыть chrome с помощью следующей команды. (Нажмите window+R)

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

Примечание: ваш chrome не должен быть открыт. При запуске этой команды chrome откроется автоматически.

Если вы вводите эту команду в командной строке, выберите каталог установки chrome и используйте эту команду.

ниже код скрипта для открытия chrome в MAC с помощью "--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 &"

второй вариант

Вы можете просто использовать "открыть" (1) чтобы добавить флаги: откройте "Google Chrome" --args --allow-file-access-from-files


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

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