Нет "Access-Control-Allow-Origin" - Node/Проблема с Apache Port

Я создал небольшой 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 "на запрошенном ресурсе. Поэтому" 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>

Ответ 1

Попробуйте добавить следующее промежуточное программное обеспечение в ваше приложение 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();
});

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

Ответ 2

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

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

var cors = require('cors');

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

Ответ 3

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

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

Ответ 4

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

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

Я храню белые списки как allowed_origins в конфигурации Express и помещаю правильный домен в соответствии с заголовком origin, так как 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);
});

Ответ 5

Код ответа разрешает только 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();
});

Ответ 6

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

npm i --save cors

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

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

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

Ответ 7

Это сработало для меня.

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

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

Вы можете изменить *, чтобы соответствовать вашим потребностям. Надеюсь, это поможет.

Ответ 8

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


});

Ответ 9

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

Ответ 10

Привет, это происходит, когда внешний и внутренний серверы работают на разных портах. Браузер блокирует ответы от бэкэнда из-за отсутствия заголовков CORS. Решение состоит в том, чтобы добавить заголовки CORS в бэкэнд-запрос. Самый простой способ - использовать пакет cors npm.

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

Это включит заголовки CORS во всех ваших запросах. Для получения дополнительной информации вы можете обратиться к документации Cors

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

Ответ 11

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

ИЛИ

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

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

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

Примечание. Ваш хром не должен быть открыт. Когда вы запустите эту команду, хром откроется автоматически.

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

Ниже script код для открытого хром в 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 &"

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

Вы можете просто использовать open (1) для добавления флагов: open -a 'Google Chrome' --args --allow-file -доступ-из файлов

Ответ 12

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