我已经使用Node/Express创建了一个小API,并试图使用Angularjs拉数据,但由于我的html页面在localhost:8888和节点API在端口3000上监听下运行,我得到了No 'Access-Control-Allow-Origin'。我尝试使用node-http-proxy和Vhosts Apache,但没有太多成功,请参阅下面的完整错误和代码。

XMLHttpRequest无法加载localhost:3000。被请求的资源上没有'Access-Control-Allow-Origin'标头。因此,不允许访问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>

当前回答

我们将看看前两个答案是否接受我的编辑,但很可能您必须添加或使用127.0.0.1而不是localhost。

使用cors包,你甚至可以使用多个允许的来源:

app.use(
  cors({ origin: ["http://localhost:8888", "http://127.0.0.1:8888"] })
);

如果您希望允许任何内容,则可以使用origin:“*”。

要了解更多信息,请查看Web Dev Simplified的教程。

其他回答

接受的答案是好的,如果你喜欢更短的东西,你可以使用一个插件称为cors可用的Express.js。

对于这种特殊的情况,使用起来很简单:

var cors = require('cors');

// use it before all route definitions
app.use(cors({origin: 'http://localhost:8888'}));

(您可能需要使用127.0.0.1而不是localhost。)

请求源需要与允许的源相匹配,你也可以有多个:

app.use(
  cors({origin: ['http://localhost:8888', 'http://127.0.0.1:8888']})
);

在NODEJ Restful api的app.js中增加如下代码,以避免在angular 6或其他框架中出现“Access-Control-Allow-Origin”错误

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"

OR

下面是周围的工作铬为本地测试

你需要使用以下命令打开你的chrome浏览器。(按窗口+ R)

Chrome.exe --allow-file-access-from-files

注意:你的chrome浏览器不能打开。当你运行这个命令时,chrome浏览器会自动打开。

如果你在命令提示符中输入这个命令,然后选择你的chrome安装目录,然后使用这个命令。

下面是在MAC中使用“——allow-file-access-from-files”打开chrome的脚本代码

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 '谷歌Chrome'——args——allow-file-access-from-files

上面的答案对我来说很好,只是我需要将多个域名列入白名单。

此外,top answer还会受到这样一个事实的影响,即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);
});

我们将看看前两个答案是否接受我的编辑,但很可能您必须添加或使用127.0.0.1而不是localhost。

使用cors包,你甚至可以使用多个允许的来源:

app.use(
  cors({ origin: ["http://localhost:8888", "http://127.0.0.1:8888"] })
);

如果您希望允许任何内容,则可以使用origin:“*”。

要了解更多信息,请查看Web Dev Simplified的教程。