1

while I am experienced in .NET and Javascript, I am currently learning React and during the fetch to my REST API I am getting this error.

Access to fetch at 'https://localhost:7142/api/Campaign' 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.

Here is my Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json.Serialization;
using Microsoft.Extensions.FileProviders;
using System.IO;

namespace WebAPI
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //Enable CORS
            services.AddCors(c => c.AddPolicy(name:"MyPolicy", options =>
            {
                options.WithOrigins("http://localhost:3000")
                       .AllowAnyMethod()
                       .AllowAnyHeader();
            }));
            
            //JSON Serializer
            services.AddControllersWithViews().AddNewtonsoftJson(options =>
            options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore)
                .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver
                = new DefaultContractResolver());

            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
           

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            //Enable CORS
            app.UseCors("MyPolicy");

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(
                   Path.Combine(Directory.GetCurrentDirectory(), "Photos")),
                RequestPath = "/Photos"
            });
        }
    }
}

I believe the issue has to deal with the CORS Policy, but have tried everything. Does anything stand out to anyone?

Here is my Campaign.js

import React,{Component} from 'react';
import { variables } from './Variables';

export class Campaign extends Component{
constructor(props){
    super(props);

    this.state={
        campaigns:[]
    }
}

refreshList(){ 
    debugger;
    //fetch(variables.API_URL+'Campaign')
    fetch('https://localhost:7142/api/Campaign')
    .then(response=>response.json())
    .then(data=>{
        this.setState({campaigns:data});
        console.log(data);
    });
}

componentDidMount(){
    this.refreshList();
}

    render(){
        const {
            campaigns
        }=this.state;

        return(
            <div>
                <table className='table table-striped'>
                    <thead>
                        <tr>
                            <th>
                                CampaignId
                            </th>
                            <th>
                                CampaignName
                            </th>
                            <th>
                                Options
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        {campaigns.map(camp=>
                            <tr key={camp.campaign_id}>
                                <td>{camp.campaign_id}</td>
                                <td>{camp.campaign_name}</td>
                                <td>
                                    <button type="button" className="btn btn-light mr-1">
                                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-square" viewBox="0 0 16 16">
                                        <path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/>
                                        <path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"/>
                                        </svg>
                                    </button>
                                    <button type="button" className="btn btn-light mr-1">
                                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
                                        <path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1H2.5zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5zM8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5zm3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0z"/>
                                        </svg>
                                    </button>
                                </td>
                            </tr>
                            )}
                    </tbody>
                </table>
            </div>
        )
    }
}

export default Campaign;
webminer07
  • 293
  • 4
  • 8
  • 25
  • 1
    Does this answer your question? [Access to fetch at from origin 'http://localhost:3000' has been blocked by CORS policy](https://stackoverflow.com/questions/61238680/access-to-fetch-at-from-origin-http-localhost3000-has-been-blocked-by-cors) And if not, see https://stackoverflow.com/search?q=%5Breactjs%5D+fetch+has+been+blocked+by+CORS+policy%3A+No+Access-Control – Ken White Mar 26 '22 at 01:57
  • Thanks for the link. I tried the no-cors mode and it gives me failed to fetch. And when i try to add the middleware im not really sure where to add it to say "const cors = require("cors"); app.use(cors());" – webminer07 Mar 26 '22 at 02:20
  • I have same issue. using of rest wcf with fetch api ? Do you change any section in web config of server side of service? – maniaq Jul 03 '22 at 10:48
  • You need to check your API server for this problem. It usually depends on the server API setting. So please check CORs setting rather than checking frontend. e.g. if your server has been built with express, you can use `cors` middleware to allow localhost. – Liki Crus Jul 17 '22 at 17:23

2 Answers2

0

Hopefully i'll be able to help you.. I'm also new to learning React and fetching. I have ran into this problem as well when i tried sending a 'POST' request to a real time database in firebase. The way I have fixed this error was to add 'folder-name.json' at the end of my url i was fetching to.

async function addMovieHandler(movie) {
const response = await fetch('https://react-http-21af5-default-rtdb.firebaseio.com/movies.json' , {
  method: 'POST',
  body: JSON.stringify(movie),
  headers: {
    'Content-type' : 'application/json'
  }
})

const data = await response.json();
console.log(data);

}

If this does not help, I have read that you'll need to install CORS in your backend server to allow data fetching. You might find useful information in this website [link]: https://www.stackhawk.com/blog/react-cors-guide-what-it-is-and-how-to-enable-it/#:~:text=CORS%20error.,React%20client%20on%20port%203000.

  • You are mudding the picture here, you cannot install CORS it is a security mechanism. The problem has to do with the API configuration, not react. – T. Nielsen Jul 20 '22 at 11:05
0

Yes this is indeed related to CORS, the Cross Origin Resource Sharing. So in essence the API is getting a request from a server identifying as localhost, this is another domain than it is and therefore it's objecting.

This is because .net wants You as a develper to opt in for foreign domain data consumption as to passively assist you against DOS attacks. What You have to do is to tell .net that this place is ok or choose to allow all places if You're that kind of person, so in Startup.cs when configuring the api

public void Configure(IApplicationBuilder app, IWebHostEnvironment env){
  //-- Obviously the kind citizen will be explicit about origins accepted, 
  // this is sort of a overruling in essence of the functionality, which 
  // is not necessarily ideal
  app.UseCors(
      x => x.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
  );
  if(YouFeel.LikeIt()){
     // alternative
     app.UseCors(
      x => x.WithOrigins(
              "http://www.yoursite.com",
              "http://localhost"       // this one should probably only run in develpment environment if you add
            ).AllowAnyMethod()
             .AllowAnyHeader()
      );
  }
}
T. Nielsen
  • 835
  • 5
  • 18