6

I've created an Angular project with yeoman's boilerplate code (generator-gulp-angular)

And now in my controller I'm trying to make a http request like this:

$http.get('http://food2fork.com/api/search?key='+key+'&page=1').then(function(response) {
    vm.all = response.data;
});

But I keep getting this error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://food2fork... (Reason: CORS header 'Access-Control-Allow-Origin' missing)

I did my research and found I needed to add this Access Control to my server, using the middleware property, which I did, but I still keep getting an error here is my server.js file

var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');
var cors = require('cors');

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

  //here is where I added the middleware 
  var server = {
    baseDir: baseDir,
    middleware: function (req, res, next) {
        res.setHeader('Access-Control-Allow-Origin', '*');
        next();
      },
    routes: routes
  };      

  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([path.join(conf.paths.tmp, '/serve'), conf.paths.src]);
});

gulp.task('serve:dist', ['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, []);
});
`

But still the error persists, any help?

Alexandre Neukirchen
  • 2,713
  • 7
  • 26
  • 36
Dwight Lisper
  • 435
  • 5
  • 9

2 Answers2

2

You are requiring http-proxy-middleware but not using it ! If You want to resolve Cross Origin for all URL containing /api, first you should forward your Angular requests to your BrowserSync Server

So

$http.get('http://food2fork.com/api/search?key='+key+'&page=1')

Should become

$http.get('/api/search?key='+key+'&page=1')

The BrowserSync will receive the call

In Browser relay the call to the real server in the back with

target :'http://food2fork.com/'

and add Cross Origin headers when the response comes back with

changeOrigin: true,

the full config becomes :

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

const jsonPlaceholderProxy = proxyMiddleware('/api', {
  target: 'http://food2fork.com/api',
  changeOrigin: true,
  logLevel: 'debug'
});

module.exports = function() {
  return {
    server: {
      middleware: [jsonPlaceholderProxy],
      baseDir:  baseDir
    }
  };
};
Gauthier Peel
  • 1,438
  • 2
  • 17
  • 35
0

You should add additional information on the server side which headers and methods are allowed. For example:

res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");

or

res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");

This will tell the server to accept the headers send by the client (e.g. Origin) as well as the HTTP methods which you plan to support (e.g. GET).

For further informations on CORS see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

oberbics
  • 408
  • 4
  • 12
  • 1
    still the same error, is this the only place I have to do that, maybe its somewhere else... `var server = { baseDir: baseDir, middleware: function (req, res, next) { res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); next(); }, routes: routes }; ` – Dwight Lisper Apr 28 '16 at 11:31
  • You should still set res.setHeader('Access-Control-Allow-Origin', '*'); as well – oberbics Apr 28 '16 at 11:36
  • Could you please post the preflight OPTIONS request? – oberbics Apr 28 '16 at 11:41
  • I would if I knew what is that :/ – Dwight Lisper Apr 28 '16 at 11:51
  • Look into your browsers developer console - when you send the request in the network tab you should see one request with method "OPTION" - and you should definitely read about CORS in the link i posted in the answer ;) – oberbics Apr 28 '16 at 11:58
  • OK, I will read, the thing is I don't see any OPTION method only ones are GET and POST (Mozilla/Network tab) – Dwight Lisper Apr 28 '16 at 12:10