如何克服"访问控制允许来源"当客户机与服务器错误 [英] How to overcome "Access-Control-Allow-Origin" error when client talks to server

查看:495
本文介绍了如何克服"访问控制允许来源"当客户机与服务器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我用从一个swiip自耕农的项目称为发电机一饮而尽角 - 只是做NPM搜索一饮而尽角,你会看到它

出了客户端从127.0.0.1:3000运行框,我希望做一个$ HTTP调用到(蟒蛇)服务上127.0.0.1:8080。它使用的浏览器同步现场重装和代理中间件使从客户端到服务器代理的调用。代理中间件是每默认禁用,因此关键是要启用并成功发出请求并从服务器接收响应。到目前为止,我还没有能够成功启用: - (

更新:我重新自耕农项目,以专注于访问控制问题上的口号是给自己一个简单的例子下面,我得到了它或多或少开箱工作,而不必诉诸修改为了让跨起源请求的服务器逻辑。令人愉快它作为说明描述的那样简单。下面是扩展了一口中间件进行代理的代理文件,或者更确切地说,映射从客户端到服务器的:

\r
\r

/ * jshint未使用:假* /\r
\r
/ ***************\r
\r
  该文件的proxy.js允许您配置插入BrowserSync一个代理系统\r
  为了重定向后端请求,同时还服务和看\r
  从Web项目文件\r
\r
  重要提示:代理默认情况下禁用。\r
\r
  如果你想启用它,看一下配置选项,最后\r
  改变`module.exports`在该文件的末尾\r
\r
*************** /\r
\r
使用严格的;\r
\r
VAR proxyMiddleware =要求('HTTP代理中间件');\r
\r
VAR的选择= {\r
  目标:http://127.0.0.1:8080\r
};\r
\r
VAR代理= proxyMiddleware('/报价',期权);\r
\r
module.exports =功能(){\r
  返回[代理]\r
}

\r

\r
\r

从gulpfile(gulpfile.js),我们有:

\r
\r

使用严格的;\r
\r
VAR一饮而尽=要求('吞掉');\r
VAR browserSync =要求('浏览器同步');\r
VAR browserSyncSpa =要求('浏览器同步温泉');\r
\r
VAR UTIL =要求('UTIL');\r
\r
VAR中间件=要求('./代理');\r
\r
module.exports =功能(选件){\r
\r
  功能browserSyncInit(BASEDIR,浏览器){\r
    浏览器浏览器=未定义===? '默认浏览器;\r
\r
    VAR路线= NULL;\r
    如果(BASEDIR === options.src ||(util.isArray(BASEDIR)及&放大器;!baseDir.indexOf(options.src)== 1)){\r
      路线= {\r
        '/ bower_components':'bower_components\r
      };\r
    }\r
\r
    VAR服务器= {\r
      BASEDIR:BASEDIR,\r
      路线:路线\r
    };\r
\r
    \r
    //\r
    //这里的相关位\r
    //\r
    server.middleware =中间件();\r
\r
    browserSync.instance = browserSync.init({\r
      startPath:'/',\r
      服务器:服务器,\r
      浏览器:浏览器\r
    });\r
  }\r
\r
  browserSync.use(browserSyncSpa({\r
    选择:[NG-APP]//只需要角度应用\r
  }));\r
\r
  gulp.task('服务',['看'],函数(){\r
    browserSyncInit([options.tmp +'/服务,options.src]);\r
  });\r
\r
  ..\r
  \r
  gulp.task('服务:E2E-dist的',['打造'],函数(){\r
    browserSyncInit(options.dist,[]);\r
  });\r
};

\r

\r
\r

如你所见,我们正在配置一饮而尽要意识到/引用上下文的客户端上使用时( HTTP ://本地主机:3000 /报价)将被映射到后端(的http://本地主机:8080 /报价) - 了解更多信息:的https:/ /github.com/chimurai/http-proxy-middleware/blob/v0.0.5/README.md

下面就是我们使客户端上的呼叫使用$ http服务:

\r
\r

函数quotePriceGenerator($ Q $ HTTP){\r
  VAR lowPrice = 1.45000,highPrice = 1.47000;\r
  VAR askPrice,sellPrice;\r
  变种服务= {};\r
  service.getPrice =功能(){\r
    变种推迟= $ q.defer();\r
    $ HTTP({\r
      网址:'/报价,\r
      方法:GET\r
    })\r
    。然后(函数(报价){\r
      VAR日期=新的日期();\r
      常量quoteZoom = 100000;\r
      常量quotePipsWindow = -3;\r
      ..\r
      。QBOX ['交易规模字符串'] = QBOX ['交易规模']的toString();\r
      service.qBox = QBOX;\r
      返回deferred.resolve(服务);\r
    });\r
    //返回分钟(含)和max之间的随机整数(包括)\r
    //使用Math.round()会给你一个非均匀分布!\r
    功能getRandomIntInclusive(最小,最大){\r
      返回Math.floor(的Math.random()*(最大 - 最小+ 1))+分钟;\r
    }\r
    返回deferred.promise;\r
  };\r
  退换货服务;\r
  ..\r
  功能randomizeAskSell(低,高){\r
\r
  }\r
}\r
\r
\r
\r
。quotePriceGenerator $注射='$ Q,$ HTTP'];\r
出口默认quotePriceGenerator;

\r

\r
\r

在后台,蟒蛇龙卷风REST API,并不需要对访问控制允许来源任何配置。在这里,它是:

\r
\r

从__future__进口部\r
进口tornado.ioloop\r
进口pyrestful.rest\r
进口随机\r
\r
从pyrestful进口mediatypes\r
从pyrestful.rest进口GET\r
\r
类引用(对象):\r
  quote_date_time =浮动\r
  ..\r
  出售价格=浮动\r
  trading_size = INT\r
\r
类QuoteResource(pyrestful.rest.RestHandler):\r
  @get(_path =/引用,_produces = mediatypes.APPLICATION_JSON)\r
  高清getQuoteJson(个体经营):\r
    PRICE_MIN = random.randint(145000,146000)/ 100000\r
    PRICE_MAX = random.randint(146000,147000)/ 100000\r
    ..\r
    quote.sell_price =出售价格\r
    quote.trading_size = trading_size\r
    回报报价\r
\r
如果__name__ ==__main__:\r
  尝试:\r
    打印(启动服务)\r
    应用= pyrestful.rest.RestService([QuoteResource])\r
    app.listen(8080)\r
    tornado.ioloop.IOLoop.instance()。开始()\r
  除了KeyboardInterrupt:\r
    打印(\\ NSTOP服务)

\r

\r
\r


解决方案

这是错误的要求的一些信息/响应将是有益的了。

您可以尝试到 changeOrigin 参数设置为true。这将修改请求的主机头相匹配的服务器的主机名。

  VAR proxyMiddleware =要求('HTTP代理中间件');VAR的选择= {
  目标:http://127.0.0.1:8080,
  changeOrigin://真LT - ; - changeOrigin
};

如果不工作;您可以添加访问控制允许来源头到响应:

  VAR proxyMiddleware =要求('HTTP代理中间件');VAR的选择= {
  目标:http://127.0.0.1:8080,
  onProxyRes:功能(proxyRes,REQ,水库){
    proxyRes.headers ['访问控制允许来源'] ='*';
  }
};

HTTP代理中间件 onProxyRes 选项在v0.5.0加入,所以一定要确保,如果你还在使用v0.0.5更新它。

So I'm using a yeoman project from swiip called generator-gulp-angular - just do "npm search gulp-angular" and you'll see it.

Out of the box the client is running from 127.0.0.1:3000 and I wish to make a $http call to a (python) service on 127.0.0.1:8080. Its using browser-sync for live reload and proxy middleware to make the proxy calls from client to server. Proxy middleware is per default disabled, so the trick is to enable it and successfully make requests to and receive responses from server. So far i've not been able to successfully enable it :-(

Update: I recreated the yeoman project following the motto "give yourself a simple example" in order to concentrate on the Access-Control issue and I got it to work more or less out of the box without having to resort to modifying the server logic in order to allow cross origin requests. Pleasingly it's as simple as the instructions describe. Here's the proxy file that extends the gulp middleware to perform the proxy, or rather mapping from client to server:

 /*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];
}

From the gulpfile (gulpfile.js) we have:

'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, []);
  });
};

As you see we're configuring gulp to be aware of the "/quote" context that when used on the client (http://localhost:3000/quote) will get mapped to the backend (http://localhost:8080/quote) - for further information: https://github.com/chimurai/http-proxy-middleware/blob/v0.0.5/README.md

Here's where we make the call on the client using the $http service:

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;

The backend, a python tornado REST API, didn't require any configuration for Access-Control-Allow-Origin. Here it is:

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")

解决方案

Some information on the erroneous request/response would be helpful too.

You could try to set the changeOrigin param to true. This will modify the request's host header to match the server's hostname.

var proxyMiddleware = require('http-proxy-middleware');

var options = {
  target: 'http://127.0.0.1:8080',
  changeOrigin: true         // <-- changeOrigin
};

If that doesn't work; you can add the Access-Control-Allow-Origin header to the response:

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-proxy-middleware onProxyRes option is added in v0.5.0 , so make sure to update it if you're still using v0.0.5

这篇关于如何克服&QUOT;访问控制允许来源&QUOT;当客户机与服务器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆