React component has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
Asked Answered
E

7

15

I am calling the Web API from the my react component using fetch when I used to run it as one application, there was no problem, but when I am running the application react separate from API, I am getting the CORS error, my fetch call is as below,

    componentDidMount() {
    console.log(clientConfiguration)

    fetch(clientConfiguration['communitiesApi.local'])
        .then((response) => {
            return response.json();                
        })
        .then(data => {
            console.log(data);
            let communitiesFromApi = data.map(community => { return { value: community, display: community } });
            this.setState({ communities: [{ value: '', display: 'Select a Community...' }].concat(communitiesFromApi) });    

        }).catch(error => {
            console.log(error);
        });
};

and my POST call using Axios as below also.

    handleDownload = (e) => {
    e.preventDefault();

    var formData = new FormData();
    formData.append('communityname', this.state.selectedCommunity);
    formData.append('files', JSON.stringify(this.state['checkedFiles']));

    let url = clientConfiguration['filesApi.local'];
    let tempFiles = clientConfiguration['tempFiles.local'];

    axios({
        method: 'post',
        responseType: 'application/zip',
        contentType: 'application/zip',
        url: url,
        data: formData
    })
        .then(res => {       
            var fileName = `${this.state['selectedCommunity']}.zip`;
            saveAs(`https://localhost:44352/TempFiles/${res.data}`, fileName);
        });
};

Here is my server side api code:

        [HttpGet("{communityName}")]
    public string Get(string communityName)
    {
        string rootPath = Configuration.GetValue<string>("ROOT_PATH");
        string communityPath = rootPath + "\\" + communityName;

        string[] files = Directory.GetFiles(communityPath);

        List<string> strippedFiles = new List<string>();
        foreach (string file in files)
        {
            strippedFiles.Add(file.Replace(communityPath + "\\", ""));
        }

        return JsonConvert.SerializeObject(strippedFiles);
    }

    [HttpPost]
    public string Post([FromForm] string communityName, [FromForm] string files) //FileContentResult
    {
        var removedInvalidCharsFromFileName = removeInvalidCharsFromFileName(files);
        var tFiles = removedInvalidCharsFromFileName.Split(',');
        string rootPath = Configuration.GetValue<string>("ROOT_PATH");
        string communityPath = rootPath + "\\" + communityName;

        byte[] theZipFile = null;

        using (MemoryStream zipStream = new MemoryStream())
        {
            using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
            {
                foreach (string attachment in tFiles)
                {
                    var zipEntry = zip.CreateEntry(attachment);

                    using (FileStream fileStream = new FileStream(communityPath + "\\" + attachment, FileMode.Open))
                    using (Stream entryStream = zipEntry.Open())
                    {
                        fileStream.CopyTo(entryStream);
                    }
                }
            }

            theZipFile = zipStream.ToArray();
        }

        ////return File(theZipFile, "application/zip", communityName + ".zip");

        string tempFilesPath = Configuration.GetValue<string>("Temp_Files_Path");

        if (!System.IO.Directory.Exists(tempFilesPath))
            System.IO.Directory.CreateDirectory(tempFilesPath);

        System.IO.File.WriteAllBytes($"{tempFilesPath}\\{communityName}.zip", theZipFile);

        //return System.IO.File.ReadAllBytes($"{tempFilesPath}\\Test.zip");

        //return $"{tempFilesPath}\\{communityName}.zip";
        return $"{communityName}.zip";
    }

And I am getting the error for Get as below: "Access to fetch at 'https://localhost:44368/api/communities' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."

Ephrayim answered 15/10, 2019 at 23:6 Comment(1)
Does your API return CORS headers? The issue/fix will be with the server side - you've shown client side code :DFriesland
U
12

You'll need to modify your sever. You'll need to

  1. Enable CORS on the server side and
  2. Add the domain where you'll be hosting your front-end to your list of Allowed Origins.
Upolu answered 15/10, 2019 at 23:13 Comment(4)
Any example or code snippet possible please? I am also researching its only one thing that's missingEphrayim
Yes I did, but for some reason it not access accepting stillEphrayim
I'm not sure, it depends what language your back-end is written in. You mentioned in your question that it used to be on the same site, so does that mean the back-end is written in NodeJS? Different languages and frameworks have different ways they handle CORS configuration. You may also be able to set your list of Allowed Origins in your web server (Apache, Nginx, etc.)Upolu
No back-end is written in ASP.Net Core, I did fix it, but now I am getting another problem that I am not able to download a file, what am I missing buddy, my error is: FileSaver.min.js:34 Access to XMLHttpRequest at 'localhost:44352/TempFiles/Community-1.zip' from origin 'localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.Ephrayim
B
7

Adding mode: 'no-cors' to the fetch method should do the trick

  fetch(clientConfiguration['communitiesApi.local'], {
    mode: 'no-cors'
  })
  .then((response) => {
      return response.json();                
  })
  .then(data => {
      console.log(data);
      let communitiesFromApi = data.map(community => { return { value: community, display: community } });
      this.setState({ communities: [{ value: '', display: 'Select a Community...' }].concat(communitiesFromApi) });    

  }).catch(error => {
      console.log(error);
  });

When using axios I like to use Allow CORS: Access-Control-Allow-Origin from chrome web store, pretty handy when developing web apps on localhost

Burchfield answered 16/10, 2019 at 3:3 Comment(2)
Not always this would work. In my case the response it got was null.Strutting
This worked for me as well but I am worried about issues this may cause down the line.Armstead
Q
4

You need to add cors on the server-side This can easily be done by stopping the server and then

npm install cors

and then adding this to your main routers file if you are using multiple files for routing

const express = require("express");
const router = express.Router();
const cors = require("cors");
router.use(cors());

and you are all setup for multi files router.

For single file router you should use the following code:

const express = require("express")
const app = express()
const cors = require("cors")

app.use(cors())

and you are all setup This should solve the error

Quartermaster answered 18/2, 2021 at 19:47 Comment(0)
E
0

thank you I could able to resolve this issue by implementing CORS on my Web API, here is the Code I did, but yours too work great in situations where the Web Api is already implemented and we need to consume the Api and there is not way to go and modify the api, then yours from the client side works. Here is my change in the Web API

public void ConfigureServices(IServiceCollection services)
{
    string configValue = Configuration.GetValue<string>("CORSComplianceDomains");
    string[] CORSComplianceDomains = configValue.Split("|,|");

    services.AddCors(options =>
    {
        options.AddDefaultPolicy(
            builder =>
            {

                builder.WithOrigins("http://localhost:3000");
            });

        options.AddPolicy("AnotherPolicy",
            builder =>
            {
                builder.WithOrigins(CORSComplianceDomains)
                                    .AllowAnyHeader()
                                    .AllowAnyMethod();
            });

    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    // In production, the React files will be served from this directory
    services.AddSpaStaticFiles(configuration =>
    {
        configuration.RootPath = "ClientApp/build";
    });
}

And added the urls in the appsettings.json file so that any user can add the new urls without much sweating.

  "CORSComplianceDomains": "http://localhost:3000|,|http://www.contoso.com"

Thank you very much - I put my answer here so that someone can get it - thanks for jumping in and helping please - I appreciated it - thank you so much.

Ephrayim answered 16/10, 2019 at 17:5 Comment(0)
W
0

I had a pretty similar issue on a react project back in the day, to fix that i had to change my package.json writing "proxy": "your origin" in my case was something like "proxy": "http://localhost:5000". Hope you can solve your issue.

Wilfordwilfred answered 5/1, 2022 at 3:45 Comment(0)
P
0

I was getting the same error in the browser logs, but I'm not using React.

Turns out I'm loading my page by IP, but my javascript calls the API using the server domain name. So the browser thinks it's a cross-site request and blocks it. If you are getting the same message and the internet search engine brought you here, check if it's not the same case for you.

If that's the case, you can solve it by finding out if the access is through domain or IP, and use that in the request, instead of having it fixed on one or the other.

Polygraph answered 4/2, 2022 at 23:5 Comment(0)
S
-1

Chrome CORS extension worked for me. Please add this extension and also watch video to ensure that you are using it correctly. Extension name: Allow CORS: Access-Control-Allow-Origin

Spradling answered 17/10, 2022 at 7:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.