Нет «Access-Control-Allow-Origin» - проблема с узлом / портом Apache

195

Я создал небольшой 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>
Теги:
express
rest
cors

11 ответов

517
Лучший ответ

Попробуйте добавить следующее промежуточное программное обеспечение в ваше приложение 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
    Можете ли вы помочь точно указать, куда это идет? У меня есть следующий код на моем сервере. Это идет сразу после этого? var app = require ('express') (), server = require ('http'). createServer (app), io = require ('socket.io'). listen (server), request = require ("request") , url = require ("url"); server.listen (6969); // это идет здесь? на новой линии?
  • 0
    Это функция промежуточного программного обеспечения. Вы можете поместить его после того , как require линий и до server.listen линии. Надеюсь, это поможет!
Показать ещё 11 комментариев
75

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

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

var cors = require('cors');

// use it before all route definitions
app.use(cors({origin: 'http://localhost:8888'}));
  • 3
    Мне пришлось использовать {origin: 'null'} чтобы он работал ... Судя по всему, мой браузер отправляет null в качестве источника?
  • 2
    Зачем изобретать велосипед. Я всегда за пакетное решение по сравнению с фрагментом кода
Показать ещё 3 комментария
24

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

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:)');
});
  • 5
    ) смайлик смутил меня
13

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

Кроме того, верхний ответ страдает тем фактом, что запрос 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);
});
  • 0
    Это то же самое 'if (app.get (' разрешено происхождение '). IndexOf (origin)! == - 1)? "?
10

Код ответа разрешает только 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();
});
  • 2
    Это не работает для меня! «* не является допустимым источником». Кажется, символ * не распознается как подстановочный знак.
  • 0
    Меня устраивает. то есть используя подстановочный знак '*'. работает как для хрома, так и для сафари.
Показать ещё 1 комментарий
5

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

npm i --save cors

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

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

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

  • 0
    "cors": "^2.8.5", "express": "^4.16.3", отлично работает только с предложенной строкой @monikaja. Спасибо!
2

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

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

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

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

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


});
1

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

Вы можете использовать "$ 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 -доступ-из файлов

  • 0
    Как насчет MAC? Chrome.exe --allow-file-access-from-files
  • 0
    / Applications / Google \ Chrome.app/Contents/MacOS/Google \ Chrome --allow-file-access-from-files удается открыть chrome, но по-прежнему отображается сообщение «XMLHttpRequest не может загрузить localhost: 3000. Источник localhost: 8888 is не разрешено Access-Control-Allow-Origin. "
Показать ещё 2 комментария
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.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню