Как преодолеть ошибку "Access-Control-Allow-Origin", когда клиент общается с сервером
Так что я использую йоменский проект от swiip под названием generator-gulp-angular - просто выполните "npm search gulp-angular", и вы увидите это.
Из коробки клиент работает с 127.0.0.1:3000, и я хочу сделать $http-вызов службы (python) на 127.0.0.1:8080. Он использует браузерную синхронизацию для перезагрузки в реальном времени и промежуточное ПО для прокси-серверов для выполнения прокси-вызовов с клиента на сервер. Промежуточное ПО по умолчанию отключено по умолчанию, поэтому хитрость заключается в том, чтобы включить его и успешно отправлять запросы и получать ответы от сервера. До сих пор я не смог успешно включить его:-(
Обновление: я воссоздал проект yeoman, следуя девизу "дай себе простой пример", чтобы сконцентрироваться на проблеме контроля доступа, и я получил более или менее готовую работу без необходимости прибегать к изменению логики сервера в Для того, чтобы разрешить перекрестные запросы происхождения. Приятно, что это так просто, как описано в инструкции. Вот файл прокси, который расширяет промежуточное программное обеспечение gulp для выполнения прокси, или, скорее, отображения между клиентом и сервером:
/*jshint unused:false */
/***************
This file proxy.js allows you to configure a proxy system plugged into BrowserSync
in order to redirect backend requests while still serving and watching
files from the web project
IMPORTANT: The proxy is disabled by default.
If you want to enable it, watch at the configuration options and finally
change the `module.exports` at the end of the file
***************/
'use strict';
var proxyMiddleware = require('http-proxy-middleware');
var options = {
target: 'http://127.0.0.1:8080'
};
var proxy = proxyMiddleware('/quote', options);
module.exports = function(){
return [proxy];
}
Из gulpfile (gulpfile.js) мы имеем:
'use strict';
var gulp = require('gulp');
var browserSync = require('browser-sync');
var browserSyncSpa = require('browser-sync-spa');
var util = require('util');
var middleware = require('./proxy');
module.exports = function(options) {
function browserSyncInit(baseDir, browser) {
browser = browser === undefined ? 'default' : browser;
var routes = null;
if(baseDir === options.src || (util.isArray(baseDir) && baseDir.indexOf(options.src) !== -1)) {
routes = {
'/bower_components': 'bower_components'
};
}
var server = {
baseDir: baseDir,
routes: routes
};
//
// Here's the relevant bit
//
server.middleware = middleware();
browserSync.instance = browserSync.init({
startPath: '/',
server: server,
browser: browser
});
}
browserSync.use(browserSyncSpa({
selector: '[ng-app]'// Only needed for angular apps
}));
gulp.task('serve', ['watch'], function () {
browserSyncInit([options.tmp + '/serve', options.src]);
});
..
gulp.task('serve:e2e-dist', ['build'], function () {
browserSyncInit(options.dist, []);
});
};
Как вы видите, мы конфигурируем gulp, чтобы знать контекст "/quote", который при использовании на клиенте ( http://localhost:3000/quote) будет привязан к бэкэнду ( http://localhost:8080/quote) - для получения дополнительной информации: https://github.com/chimurai/http-proxy-middleware/blob/v0.0.5/README.md
Вот где мы звоним клиенту, используя сервис $http:
function quotePriceGenerator($q, $http) {
var lowPrice = 1.45000, highPrice = 1.47000;
var askPrice, sellPrice;
var service = {};
service.getPrice = function() {
var deferred = $q.defer();
$http({
url: '/quote',
method: 'GET'
})
.then(function(quote) {
var date = new Date();
const quoteZoom = 100000;
const quotePipsWindow = -3;
..
qBox['trading-size-string'] = qBox['trading-size'].toString();
service.qBox = qBox;
return deferred.resolve(service);
});
// Returns a random integer between min (included) and max (included)
// Using Math.round() will give you a non-uniform distribution!
function getRandomIntInclusive(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
return deferred.promise;
};
return service;
..
function randomizeAskSell(low, high){
}
}
quotePriceGenerator.$inject = ['$q', '$http'];
export default quotePriceGenerator;
Бэкэнд, API REST торнадо Python, не требовал никакой конфигурации для Access-Control-Allow-Origin. Вот:
from __future__ import division
import tornado.ioloop
import pyrestful.rest
import random
from pyrestful import mediatypes
from pyrestful.rest import get
class Quote(object):
quote_date_time = float
..
sell_price = float
trading_size = int
class QuoteResource(pyrestful.rest.RestHandler):
@get(_path="/quote", _produces=mediatypes.APPLICATION_JSON)
def getQuoteJson(self):
price_min = random.randint(145000,146000)/100000
price_max = random.randint(146000,147000)/100000
..
quote.sell_price = sell_price
quote.trading_size = trading_size
return quote
if __name__ == "__main__":
try:
print("Start the service")
app = pyrestful.rest.RestService([QuoteResource])
app.listen(8080)
tornado.ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
print("\nStop the service")
2 ответа
Некоторая информация об ошибочном запросе / ответе также будет полезна.
Вы можете попытаться установить changeOrigin
парам к истине. Это изменит заголовок узла запроса, чтобы он соответствовал имени узла сервера.
var proxyMiddleware = require('http-proxy-middleware');
var options = {
target: 'http://127.0.0.1:8080',
changeOrigin: true // <-- changeOrigin
};
Если это не сработает; Вы можете добавить Access-Control-Allow-Origin
заголовок к ответу:
var proxyMiddleware = require('http-proxy-middleware');
var options = {
target: 'http://127.0.0.1:8080',
onProxyRes: function (proxyRes, req, res) {
proxyRes.headers['Access-Control-Allow-Origin'] = '*';
}
};
HTTP-прокси-промежуточное программное обеспечение onProxyRes
опция добавлена в v0.5.0, поэтому обязательно обновите ее, если вы все еще используете v0.0.5
Вы должны настроить прокси-сервер для пересылки ваших запросов, настроить обратный прокси-сервер или настроить CORS на внутреннем сервере, чтобы разрешить перекрестный запрос.