-1

From the front end and through jQuery I am making GET requests to a node/express app. This app then speaks to the spotify API to authenticate a user. I am getting the following error message when I try and make a call to the presave endpoint.

:8000/#access_token=AccessTokenProvidedBySpotify XMLHttpRequest cannot load http://XXX.XX.XXX.XXX/presave. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://XXX.XX.XXX.XXX:8000' is therefore not allowed access.

I have tried adding the following code to my app.js express app, but it didn't work. I tried everything else i could find online too, but cannot get it working.

var app = express();
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.get('/presave', function(req, res){
    var options = {
        url: 'https://api.spotify.com/v1/me',
        headers: {
            'Authorization': 'Bearer ' + access_token
        },
        json: true
    };

    requestPromise(options).then(function(body) {
        userEmail = body.email;
        userId = body.id;
        var optionsTwo = {
            url: 'https://api.spotify.com/v1/users/' + userId + '/playlists',
            headers: {
                'Authorization': 'Bearer ' + access_token
            },
            json: true
        };
        return rp(optionsTwo).then(function (body) {
            playlists = body.items;
            res.json(playlists);
        });
    }).catch(function (err) {
        console.log(err)
    })
});

EDIT

I have also implemented the answer provided below, but this doesn't work either. If I console.log(req.method) it is always GET, it never shows OPTIONS.

var app = express();
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  if (req.method === 'OPTIONS') {
    return res.send(200);
  } else {
    return next();
  }
});

My front end code looks like this:

$.ajax({
    type: 'GET',
    url: 'http://xxx.xx.xxx.xxx/presave',
    contentType: 'application/json',
    success: function(data) {
        console.log(data)
    }
});
  • There is a small typo in this line: `app.get('/presave', function(req, res){]`. Redundant `]` at the end. – idmitme Dec 02 '16 at 17:41
  • @SphDev sorry, typo, its not like that in my code –  Dec 02 '16 at 17:42
  • you're not responding to preflight requests, as the error suggests. – Kevin B Dec 02 '16 at 17:45
  • @KevinB ok, any guidance as to how this error can be eradicated? –  Dec 02 '16 at 17:48
  • Here is a [similar question](http://stackoverflow.com/questions/298745/how-do-i-send-a-cross-domain-post-request-via-javascript) – idmitme Dec 02 '16 at 17:50
  • Yes, respond to the preflight request. Currently it's just timing out or getting 404 – Kevin B Dec 02 '16 at 17:51
  • @KevinB is it timing out? The error message shows in the console immediately –  Dec 02 '16 at 17:52
  • That would suggest you have proper express error handling, which is ending the request that wasn't responded to. – Kevin B Dec 02 '16 at 17:53
  • @KevinB ah ok, thanks very much. Do you have a link to somewhere explaining how to respond to the preflight request in express correctly? The link above is a bit more php focussed –  Dec 02 '16 at 17:54
  • well, you respond to a get request using app.get, how would you respond to an options request? – Kevin B Dec 02 '16 at 17:55
  • `app.options`? :-) –  Dec 02 '16 at 17:56
  • indeed. it's no different, other than the response should be empty. – Kevin B Dec 02 '16 at 17:57
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/129647/discussion-between-phantom-and-kevin-b). –  Dec 02 '16 at 17:57
  • so should it just be `app.options()`? what should go inside there? –  Dec 02 '16 at 18:00
  • respond with a 200 status code. what else – Kevin B Dec 02 '16 at 19:13
  • @KevinB i have implemented the code in the answer below, but it still doesn't work. When I check `console.log(req.method)` it is always a `GET` request. It never says `OPTIONS` –  Dec 05 '16 at 09:35
  • Then are you still getting a CORS error? what specifically does it say? – Kevin B Dec 05 '16 at 16:08

1 Answers1

1

The error message "preflight request doesn't pass access control check" says the failure was caused by the preflight request rather than the post request. So you need to let the prerlight request passes.

var app = express();
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  if (req.method === 'OPTIONS') {
    return res.send(200);
  } else {
    return next();
  }
});

app.get('/presave', function(req, res){
   res.send('here');
});

On the front end side, the ajax call should use GET

$.ajax({
    type: 'GET',
    url: 'http://xxx.xx.xxx.xxx/presave',
    contentType: 'application/json',
    success: function(data) {
        console.log(data)
    }
});
Anthony C
  • 2,117
  • 2
  • 15
  • 26
  • I have no idea why, as this looks like it should work, but I am still getting the same error. When I check `console.log(req.method)` it is always a `GET` request. It never says `OPTIONS` –  Dec 05 '16 at 09:31
  • the type of your ajax call should be `Get`. I updated my answer – Anthony C Dec 05 '16 at 16:38
  • Apologies, it was `GET` in my jQuery code. This is not the issue, this looks like a real tricky one to figure out –  Dec 05 '16 at 16:50
  • I see you updated the ajax to use `Get`. However, you also updated the app to use `post` at the express side. which one is the correct one? Also, is the CROS error thrown by express, or when you are making request to `https://api.spotify.com/v1/me` ? – Anthony C Dec 05 '16 at 17:21
  • sorry man, it should be `app.get` too. I changed the code a bit to simplify the example a bit at the start, but now its all the same as i have. That is one thing, I am not entirely sure if the CORS error is express or the request to spotify. I believe that it is `express` but as none of these solutions are working perhaps it is spotify. I would have thought that i would have seen something online, and that it would be more common if it was spotift? –  Dec 05 '16 at 18:00
  • Just for testing, can you try w/ `app.get('/presave', function(req, res){ res.send('here'); });` to see if the error is from your side or from spotify side? – Anthony C Dec 05 '16 at 18:19
  • will check it tomorrow when I have the code in front of me again! Thanks for all your help –  Dec 05 '16 at 20:51
  • looks like it never hits that route as. Just before it does it gives the error message, and in my console it never shows `'getting here'`, as I did `console.log('getting here')`. Does this mean it is an issue on my side or spotify? From what I can tell it is not being allowed to hit that route –  Dec 06 '16 at 11:28
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/129899/discussion-between-phantom-and-anthony-c). –  Dec 06 '16 at 11:28