当前位置: 动力学知识库 > 问答 > 编程问答 >

angularjs - Express/Angular/Browsersync CORS - No 'Access-Control-Allow-Origin' 403 (forbidden)

问题描述:

I'm as junior as it gets when it comes to web development so please bear with me on this. I'm attempting to access data from the USDA Food Composition Databases NDB API - https://ndb.nal.usda.gov/ndb/doc/index

via an angular $http request from localhost. I'm using an express server and gulp/browsersync and am encountering two errors:

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

and

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.

I've tried setting my CORS headers in browsersync as well as my express server but I simply cannot get around this issue. Here is how I've configured the relevant code for this:

The $http request

(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);

}

}

}

})();

My Browersync/Express Server

'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;

}

})();

I'm using gulp and browsersync to serve locally over localhost:8080 but no matter what I try (setting headers in express, setting headers in browsersync, setting browsersync cors option to 'true', setting browsersync https options to true, switching my 'Access-Control-Allow-Origin' to '*' or to "localhost:8080") none of it seems to work. I suspect the NDB API has forbidden my access but I can't get in contact with them to ask about it. Their suggested contact us link - "https://api.data.gov/contact/" leads to nothing.

Any suggestions or tips on this would be greatly appreciated. I'm a total noob here in terms of web development as well as posting to Stack Overflow so please let me know if my question doesn't make any sense and needs further clarification.

网友答案:

I was fortunate enough to stumble upon a solution although I don't quite understand what's happening and would certainly like to.

Turns out I was attempting to run a local server while using my VPN (https://www.privateinternetaccess.com/) which for some reasons was causing my CORS issue. Once I turned the VPN off and began using my local network I was able to run my server and make my requests without a hitch.

I'm not sure why using my VPN would cause a 403 but my guess would be that the API I was attempting to access simply does not allow request from a remote network like the one I was using. I will look into it more and update my answer shortly.

网友答案:

Try serving from https and not http when making your API calls. Being that you are fetching an https location, but issuing an http request, you will get CORS issue.

Look into: https://nodejs.org/api/https.html

分享给朋友:
您可能感兴趣的文章:
随机阅读: