0

I am trying to request JSON data from the Genius API from a browser using Webpack and Axios.

This is a Cross-Origin Request, which I know is sometimes tricky. For a while I was getting the following error:

Failed to load https://api.genius.com/songs/378195: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.

So I then added Access-Control-Allow-Origin: * to the headers. Now I get the following error when I try to run npm run build:

You may need an appropriate loader to handle this file type.
| const headers = {
|   Authorization: `Bearer ${ACCESS_TOKEN}`,
|   Access-Control-Allow-Origin: *
| };
| 

Below is my entry index.js that is being bundled, with my access token removed. I know that webpack 2.x^ loads JSON by default. Any tips on where to go from here?

index.js

const axios = require('axios');

const ACCESS_TOKEN = "XXXXXXXXXXXXXX";
const id = '378195';
const url = `https://api.genius.com/songs/${id}`
const headers = {
    Authorization: `Bearer ${ACCESS_TOKEN}`,
    "Access-Control-Allow-Origin": "*"
};

window.newSong = function {
    axios.get(url, { headers })
    .then(response => {
        console.log(response.data.response.song);
    })
    .catch(error => {
        console.log(error);
    });
}

webpack.config.js

const path = require('path');

const config = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
};
module.exports = config;
Evan
  • 43
  • 1
  • 7

2 Answers2

1

Your headers definition is not valid JavaScript. If the key of an object contains any special characters that are reserved in the language, you have to quote it, because it is not parsed as an identifier. For example: Access-Control is equivalent to Access - Control, that's a subtraction and spaces around the operator don't make a difference for the parser.

The value you give it, isn't valid JavaScript either, because * is the multiplication operator, which expects two operands (left and right). If you want the literal value, that should be a string.

const headers = {
    Authorization: `Bearer ${ACCESS_TOKEN}`,
    "Access-Control-Allow-Origin": "*"
};
Michael Jungo
  • 31,583
  • 3
  • 91
  • 84
  • Thank you for point this out. However, I've made the above changes and now I'm getting the first error in my original question -- `No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.` Any ideas? – Evan Oct 14 '17 at 15:38
  • 1
    The `Access-Control-Allow-Origin` header is for the response (from the server), not for the request. For details see [How does Access-Control-Allow-Origin header work?](https://stackoverflow.com/questions/10636611/how-does-access-control-allow-origin-header-work). I'm not sure what exactly the problem is, but it might be related to their API, because it seems that they don't handle the `OPTIONS` preflight request properly. – Michael Jungo Oct 14 '17 at 17:25
0

It looks like you are building a client side only app. In this scenario, I found that passing the access token via the auth header doesn't work. But using a query param does.

I'm not sure why, at the time of writing, the documentation doesn't explicitly mention this.

Using An Access Token

To make authenticated requests with an access token, include it in an HTTP Authorization header preceded by the word "Bearer" and a space. For example, the value of the header could be Bearer 1234tokentokentoken.

Passing the token in the authorization header is the preferred way to authenticate API requests. However, the API also supports providing the token as the access_token query parameter of a GET request or element of a POST body.

So the url for the request should look something like:

https://api.genius.com/songs/${id}?access_token=${ACCESS_TOKEN}
marwan
  • 11
  • 3