How do I fix CORS issue in Fetch API

58,591

Solution 1

That API appears to be permissive, responding with Access-Control-Allow-Origin:*

I haven't figured out what is causing your problem, but I don't think it is simply the fetch API.

This worked fine for me in both Firefox and Chrome...

fetch('http://ip-api.com/json')
   .then( response => response.json() )
   .then( data => console.log(data) )

Solution 2

if you are making a post, put or patch request, you have to stringify your data with body: JSON.stringify(data)

fetch(URL, 
        {
            method: "POST", 
            body: JSON.stringify(data),
            mode: 'cors',
            headers: {
                'Content-Type': 'application/json',
            }
        }
    ).then(response => response.json())
    .then(data => {
        ....
    })
    .catch((err) => {
        ....
        })
    });

Solution 3

You should use the proxy solution, but pass it the IP of the client instead of the proxy. Here is an example URL format for the API you specified, using the IP of WikiMedia:

http://ip-api.com/json/208.80.152.201

Share:
58,591
Thidasa Pankaja
Author by

Thidasa Pankaja

Passionate Software Engineer at Twire working towards achieving professional goals, with an active drive to learn new technologies. Skilled in JavaScript, React, Go, PostgreSQL etc. Strong engineering professional with a Bachelor of Science (Hons) focused in Information Technology from University of Moratuwa.

Updated on July 09, 2022

Comments

  • Thidasa Pankaja
    Thidasa Pankaja almost 2 years

    I'm building a front-end only basic Weather App using reactjs. For API requests I'm using Fetch API. In my app, I'm getting the current location from a simple API I found and it gives the location as a JSON object. But when I request it through Fetch API, I'm getting this error.

    Failed to load http://ip-api.com/json: Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.
    

    So I searched through and found multiple solutions to fix this.

    1. Enabling CORS in Chrome solves the error but when I deploy the app on heroku, how can I access it through a mobile device without running into the same CORS issue.
    2. I found an proxy API which enables the CORS requests. But as this is a location request, this gives me the location of the proxy server. So it's not a solution.
    3. I've gone through this Stackoverflow question and added the headers to the header in my http request but it doesn't solve the problem. (Still it gives the same error).

    So how can I solve the issue permanently ? What's the best solution I can use to solve the CORS issue for http requests in Fetch API ?

  • Thidasa Pankaja
    Thidasa Pankaja about 6 years
    This works. But hard-coding IP as this will be a problem when I log in from a different IP right ? So how can I get the client IP as the IP is in the response object. So how can I get the IP before send the request (to attach in the request as you've mentioned) ?
  • Tallboy
    Tallboy about 6 years
    To make a proxy you need server side code (like PHP, ruby, etc). You would simply look at the IP of the incoming request, use that in the URL, get the response (in PHP still), take THAT response and then send it to the actual browser (so the browser is not the one making the request). That will bypass the CORS restrictions because the file is placed on your own domain, and CORS no longer applies.
  • Tallboy
    Tallboy about 6 years
    You won't be able to do this in JS alone unless you use JSONP, it appears they support it: ip-api.com/docs/api:json
  • Thidasa Pankaja
    Thidasa Pankaja about 6 years
    I've added the header Access-Control-Allow-Origin:* in Fetch API request. But it don't solve the problem. It works only when I enable the CORS in the browser using a plugin.
  • Brent Bradburn
    Brent Bradburn about 6 years
    I seem to be missing something, but you should not be adding Access-Control-Allow-Origin:* to your request -- the API server puts that in their response. Which they do, according to my test.
  • Thidasa Pankaja
    Thidasa Pankaja about 6 years
    After reading about adding headers and many things I've added headers in my request. And I replaced the whole fetch API request with what you mentioned and it works a charm. Thanks a lot
  • Thidasa Pankaja
    Thidasa Pankaja about 6 years
    Thanks. I'll look into that. btw, seems like it was a issue with headers in my request. Fixed it by replacing a simple code which the other guy has mentioned and it works like charm
  • mndv
    mndv almost 3 years
    It worked for me with this args: fetch('http://ip-api.com/json', { method: "GET", mode: 'cors', headers: { 'Content-Type': 'application/json',}}).then(response => response.json()) Thanks to Nafiu Lawal
  • MC9000
    MC9000 over 2 years
    how to do this with get request?