【问题标题】:Express/Angular/Browsersync CORS - No 'Access-Control-Allow-Origin' 403 (forbidden)Express/Angular/Browsersync CORS - 没有 'Access-Control-Allow-Origin' 403(禁止)
【发布时间】:2017-03-28 11:07:45
【问题描述】:

在 Web 开发方面,我还很初级,所以请多多包涵。我正在尝试从美国农业部食品成分数据库 NDB API 访问数据 - https://ndb.nal.usda.gov/ndb/doc/index

通过来自本地主机的角度 $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 以及我的 express 服务器中设置我的 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);
   }
 }
}
})();

我的浏览器同步/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, []);
});

我的 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”切换为“*”或“localhost:8080”)似乎都不起作用。我怀疑 NDB API 禁止了我的访问,但我无法联系到他们询问此事。他们建议的联系我们链接-“https://api.data.gov/contact/”一无所获。

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

【问题讨论】:

    标签: angularjs express cors


    【解决方案1】:

    我很幸运地偶然发现了一个解决方案,尽管我不太了解正在发生的事情,当然也想了解。

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2014-01-20
        • 1970-01-01
        • 2018-12-12
        • 2021-02-20
        • 2016-12-25
        • 2017-10-24
        • 2021-05-12
        • 2014-11-20
        • 2020-04-07
        相关资源
        最近更新 更多