POSTing to external API throws CORS but it works from Postman

Cristian G picture Cristian G · Dec 8, 2018 · Viewed 27.1k times · Source

I am using the imgur api to upload images via a node js app.

I am converting images to base64 strings and sending them via Postman works great.

I use node-fetch to make api calls.

const fetch = require('node-fetch')
...
async uploadImage(base64image) {
        try {
            const url = 'https://api.imgur.com/3/image'
            const res = await fetch(url,
                {
                    method: 'POST',
                    body: { image: base64image },
                    headers: {
                        'content-type': 'application/json',
                        'Authorization': 'Client-ID [my-client-id]',
                        'Access-Control-Allow-Headers': 'Content-Type, Authorization, Access-Control-Allow-Headers',
                        'Access-Control-Allow-Methods': 'POST',
                    }
                }
            )

            console.log(res)
        } catch(err) {
            console.log(err)
        }
    }

Error: Access to fetch at 'https://api.imgur.com/3/image' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers in preflight response.

I have tried many 'Access-Control-Allow-xxx' headers but none of them worked..

I assume it must be something simple that I am missing. I have been stuck on this for hours please help me.

Answer

Jatin Gupta picture Jatin Gupta · Sep 7, 2019

Browser restricts HTTP requests to be at the same domain as your web page, so you won't be able to hit imgur api directly from the browser without running into CORS issue.

I am converting images to base64 strings and sending them via Postman works great.

That's because Postman is not a browser, so is not limited by CORS policy.

I have tried many 'Access-Control-Allow-xxx' headers but none of them worked..

These headers must be returned by the server in response - in your case by the imgur server. You can't set them in the request from browser, so it'll never work.

Error: Access to fetch at 'https://api.imgur.com/3/image' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers in preflight response.

Possible solutions to your problem:

  1. If you have access to the backend api you can set the "Access-Control-Allow-Origin" header on the server and let your app access the api - but as you won't have access to the imgur server - you probably can't do that.

  2. Disable CORS in the browser - you can use a plugin like: https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en. This workaound should be fine for development. The plugin will disable your CORS settings and you will be able to hit imgur apis.

  3. The third solution is using a proxy. You can setup a small node server using express. You will then hit your own node server, which in turn will hit the imgur api. As node server is not a browser environment, it won't have any CORS issue and you will be able to access imgur API that way. This is also the reason you were able to hit the API from Postman without any issues. As Postman is not a browser environment, it's not limited by CORS policy.