Express / Angular / Browsersync CORS - No' Access-Control-Allow-Origin' 403(禁止)

时间:2016-11-14 18:05:58

标签: angularjs express cors

我在网络开发方面的初级水平,所以请耐心等待。我试图从USDA食品成分数据库NDB API访问数据 - https://ndb.nal.usda.gov/ndb/doc/index

通过来自localhost的角度$ http请求。我使用快速服务器和gulp / browsersync并遇到两个错误:

Failed to load resource: http://api.nal.usda.gov/ndb/list?format=json&It=f&max=20&sort=n&offset=15&api_key=API_KEY the server responded with a status of

XMLHttpRequest cannot load http://api.nal.usda.gov/ndb/list?format=json&It=f&max=20&sort=n&offset=15&api_key=API_KEY. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 403.

我已尝试在browsersync和我的快速服务器中设置我的CORS标头,但我根本无法解决此问题。以下是我为此配置相关代码的方法:

$ http请求

(function() {
'use strict';

angular
 .module('commonSenseDietApp')
 .factory('getFoodNamesOnly', getFoodNamesOnly);

 /** @ngInject */
function getFoodNamesOnly($log, $http, devEnvironment) {

  var service = {
    ndbApiKey: devEnvironment.api_key,
    ndbApiUrl: devEnvironment.api_url,
    getFoodNamesList: getFoodNamesList
  };

  return service;

 function getFoodNamesList(limit) {
   if(!limit) {
     limit = 30;
   }

  // For a list of all request parameters visit - https://ndb.nal.usda.gov/ndb/doc/apilist/API-LIST.md
  return $http.get(service.ndbApiUrl + '/ndb/list?format=json&It=f' + '&max=' + limit + '&sort=n&offset=15&api_key=' + service.ndbApiKey)
      .then(returnFoodNamesList)
      .catch(getFoodNamesFail);


  function returnFoodNamesList(response) {
    return response.data;
  }

   function getFoodNamesFail(err) {
     // return $log.error(err.data);
     return console.log(err);
   }
 }
}
})();

我的Browersync / Express服务器

'use strict';

var express = require('express');
var cors = require('cors');
var bodyParser = require('body-parser');
var http = require('http')


// require database data modeling via mongoose
var mongoose = require('mongoose');

var session = require('express-session');
var cookieParser = require('cookie-parser');

var flash = require('connect-flash');


// Use express and set it up
var app = express();
app.use(cors());
app.use(function (req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
  res.setHeader('Access-Control-Allow-Credentials', false);
 next();
});

app.set('views', __dirname + '/views');
app.use(express.static(__dirname + '/'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json())


var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');
var browserSync = require('browser-sync');
var browserSyncSpa = require('browser-sync-spa');

var util = require('util');

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

function browserSyncInit(baseDir, browser) {
 browser = browser === undefined ? 'default' : browser;

 var routes = null;
 if(baseDir === conf.paths.src || (util.isArray(baseDir) &&     baseDir.indexOf(conf.paths.src) !== -1)) {
 routes = {
   '/bower_components': 'bower_components'
  };
 }

var server = {
 baseDir: baseDir,
 routes: routes,
 middleware: function (req, res, next) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, content-type');
  // to the API (e.g. in case you use sessions)
  res.setHeader('Access-Control-Allow-Credentials', false);
  next();
 }
};

browserSync.instance = browserSync.init({
  startPath: '/',
  cors: true,
  browser: browser,
  notify: true,
  port: 8080,
  server: server,
 });
}

browserSync.use(browserSyncSpa({
 selector: '[ng-app]'// Only needed for angular apps
}));

gulp.task('serve', ['setenvconstants','watch'], function () {
  browserSyncInit([path.join(conf.paths.tmp, '/serve'), conf.paths.src]);
});

gulp.task('serve:dist', ['setenvconstants','build'], function () {
 browserSyncInit(conf.paths.dist);
});

gulp.task('serve:e2e', ['inject'], function () {
 browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
});

gulp.task('serve:e2e-dist', ['build'], function () {
 browserSyncInit(conf.paths.dist, []);
});

My Angular .config

(function() {
'use strict';

angular
  .module('commonSenseDietApp')
  .config(config);

/** @ngInject */
function config($logProvider, $httpProvider) {
  // Enable log
 $logProvider.debugEnabled(true);

 // For Access-Control-Allow-Origin and Set-Cookie header
 $httpProvider.defaults.withCredentials = false;
}

})();

我使用gulp和browsersync在localhost上本地服务:8080但无论我尝试什么(在express中设置标头,在browsersync中设置标头,将browsersync cors选项设置为' true',将browsersync https选项设置为true,将我的' Access-Control-Allow-Origin'切换到' *'或者#34; localhost:8080")似乎没有一个上班。我怀疑NDB API禁止我访问,但我无法与他们联系询问。他们建议联系我们链接 - " https://api.data.gov/contact/"没有任何结果。

对此有任何建议或提示将不胜感激。我在网络开发以及发布到Stack Overflow方面都是一个总菜鸟,所以如果我的问题没有任何意义并且需要进一步澄清,请告诉我。

2 个答案:

答案 0 :(得分:0)

我有幸偶然发现了一个解决方案,虽然我不太明白发生了什么,但肯定会喜欢。

原来我试图在使用我的VPN(https://www.privateinternetaccess.com/)时运行本地服务器,由于某些原因导致我的CORS问题。一旦我关闭VPN并开始使用我的本地网络,我就能够运行我的服务器并毫不费力地提出我的请求。

我不确定为什么使用我的VPN会导致403,但我的猜测是我试图访问的API只是不允许来自我正在使用的远程网络的请求。我会更多地研究它并尽快更新我的答案。

答案 1 :(得分:-1)

在进行API调用时尝试使用https而不是http。由于您正在获取https位置,但发出http请求,您将收到CORS问题。

查看:https://nodejs.org/api/https.html