Я создал небольшой 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>
Попробуйте добавить следующее промежуточное программное обеспечение в ваше приложение 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'}));
{origin: 'null'}
чтобы он работал ... Судя по всему, мой браузер отправляет null
в качестве источника?
Другой способ, просто добавьте заголовки к вашему маршруту:
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
в конфигурации 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);
});
Код ответа разрешает только 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.
"cors": "^2.8.5", "express": "^4.16.3",
отлично работает только с предложенной строкой @monikaja. Спасибо!
Это сработало для меня.
app.get('/', function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.send('hello world')
})
Вы можете изменить *, чтобы соответствовать вашим потребностям. Надеюсь, это поможет.
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();
}
});
//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
}));
Вы можете использовать "$ 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 -доступ-из файлов
/**
* 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.
require
линий и доserver.listen
линии. Надеюсь, это поможет!