Ні "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.