Ні "Access-Control-Allow-Origin" - випуск порту вузла / Apache


260

Я створив невеликий API за допомогою Node / Express і намагаюся витягнути дані за допомогою Angularjs, але так як моя HTML-сторінка працює під apache на localhost: 8888 і API вузла прослуховується на порту 3000, я отримую Ні-Контроль доступу Дозволити-походження '. Я спробував використовувати 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.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>

Відповіді:


621

Спробуйте додати наступне проміжне програмне забезпечення до програми 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') (), сервер = requ ('http'). createServer (додаток), io = requ ('socket.io'). Слухати (сервер), request = вимагати ("запит") , url = вимагати ("url"); server.listen (6969); // чи йде вона сюди? на новій лінії?
Art Geigel

1
@jvandemo чи потрібно мені змінити app.get ('/', функцію (req, res) на ... функцію (req, res, next)?
Sangram Singh

10
Ви зараз моя улюблена людина. Дякую. Чи можемо ми додати зауваження, що цей код має відбуватися до того, як маршрути будуть визначені для нообів, як я?
гегілам

1
Як зробити цю роботу під час використання модуля запиту?
Rohit Tigga

2
У моєму випадку це не спрацювало. Ця помилка все ще отримує: "Відповідь на запит перед польотом не проходить перевірку контролю доступу: на запитуваному ресурсі немає заголовка" Access-Control-Allow-Origin ". Походження" abc.xyz.net:212 "не дозволяється доступ. Відповідь мала код статусу HTTP 500. "
user1451111

96

Прийнята відповідь чудова, якщо ви хочете щось коротше, ви можете використовувати плагін під назвою 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
Навіщо винаходити колесо. Я завжди за розфасоване рішення порівняно з фрагментом коду
П’єром

мила маленька бібліотека, яка досить добре розглядала мої випадки використання бажаючих різних методів різного походження ... і менше стомлення коду для наступного хлопця, який на це дивиться.
Кайл Бейкер

6
Дякую, app.use(cors({origin: '*'}));працювали для мене, відповідно до умовно-корисних можливостей .
danialk

2
Я пропоную переглянути сторінку npm cors, щоб краще використати її. Це дуже зрозуміло для мене =).
13013SwagR

30

Ще один спосіб - просто додати заголовки до маршруту:

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

8
)смайлик збентежив мене
diEcho

17

Верхній відповідь працював відмінно для мене, за винятком того, що мені потрібно , щоб білий список доменів більш ніж один.

Крім того, головна відповідь страждає від того, що 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);
});

Це те саме "if (app.get (" дозволене походження "). IndexOf (походження)! == - 1)?"?
Rune Jeppesen

13

Код відповіді дозволяють лише 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
Це не працює для мене! "* не є коректним походженням". Здається, символ * не розпізнається як майна.
Франческо

Це працює для мене. тобто використовуючи підстановку "*". працює як для хрому, так і для сафарі.
AnBisw

Дякую;) Відмінно працює
Мауро

9

Встановіть залежність від корів у своєму проекті:

npm i --save cors

Додайте до файлу конфігурації вашого сервера наступне:

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

Він працює для мене з версією 2.8.4 cors.


"cors": "^2.8.5", "express": "^4.16.3",працює чудово просто із запропонованою лінією @monikaja. Дякую!
RamiroIsBack

Для цього потрібно надати всім джерелам доступу до програми, що зазвичай не хочеться робити. Замість цього вкажіть лише дозволені домени.
Лачо Томов

7

Це працювало для мене.

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

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

Ви можете змінити * відповідно до своїх потреб. Сподіваюсь, це може допомогти.


7

Привіт, це трапляється, коли передній кінець та бекенд працює на різних портах. Веб-переглядач блокує відповіді з бекенда через відсутність заголовків CORS. Рішення полягає в тому, щоб зробити додавання заголовків CORS у запит бекенда. Найпростіший спосіб - використовувати пакет nors cors.

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

Це дозволить заголовки CORS у всіх ваших запитах. Для отримання додаткової інформації ви можете ознайомитися з документацією на колеса

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


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


});

2

Додайте наступний код у app.js NODEJ Restful api, щоб уникнути помилки "Access-Control-Allow-Origin" у кутовій 6 або будь-якій іншій рамці

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

Примітка: Ваш хром не повинен бути відкритим. Після запуску цієї команди хром відкриється автоматично.

Якщо ви вводите цю команду в командному рядку, тоді виберіть каталог хромування, а потім скористайтеся цією командою.

Нижче коду сценарію для відкритого хрому в 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-access-from-files


Як щодо MAC ?? Chrome.exe - дозволити-отримати доступ до файлів
user1336103

/ Програми / Google \ Chrome.app/Contents/MacOS/Google \ Chrome - дозволити-файл-доступ-з-файлів вдається відкрити хром, але все ще відображається повідомлення "XMLHttpRequest не може завантажити localhost: 3000. Origin localhost: 8888 is не дозволено Access-Control-Allow-Origin. "
користувач1336103

+1 Я можу підтвердити, що це працює за допомогою опції Mac, використовуючи "відкрити". Мій випадок трохи інший, тому що я просто тестую повністю завантажений сайт, який має доступ до деяких локальних файлів JSON.
губка

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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.