Reputation: 561
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."
Upvotes: 15
Views: 69617
Reputation: 21
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
Upvotes: -1
Reputation: 4438
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.
Upvotes: 0
Reputation: 1
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.
Upvotes: 0
Reputation: 159
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
Upvotes: 4
Reputation: 561
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.
Upvotes: 0
Reputation: 143
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
Upvotes: 8
Reputation: 190
You'll need to modify your sever. You'll need to
Upvotes: 12