My Nodejs restful service has the following endpoint http://localhost:3000/api/countries. I am using this middleware https://github.com/expressjs/cors. I have cors enabled thus:-
const cors = require('cors');
app.use(cors({
'allowedHeaders': ['sessionId', 'Content-Type'],
'exposedHeaders': ['sessionId'],
'origin': '*',
'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
'preflightContinue': false
}));
I have the following code in my Angular 6 app hosted at http://localhost:4200
import { HttpClient, HttpHeaders } from '@angular/common/http';
httpClient: HttpClient;
getCountries(): Observable<any> {
const url = 'http://localhost:3000/api/countries';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin':'*'
})
};
return this.httpClient.get(url, httpOptions).pipe(
map((result: any) => {
return result;
})
);
}
I have the following code in my React App at http://localhost:3001
getCountries() {
const url = 'http://localhost:3000/api/countries';
const init = {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
};
try {
const response = await fetch(url, init);
const json = await response.json();
return json
};
}
My react code works perfectly giving the desired response, but the Angular 6 gives the following error:-
Access to XMLHttpRequest at 'http://localhost:3000/api/countries' from origin 'http://localhost:4200' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
What am I doing wrong in my angular 6 code?
Please note that I have seen answers to similar questions suggesting using a json file (proxy.conf.json) to act as a proxy server or install a chrome extension. These are not options for me.
Thanks in advance of your helpful responses.
CORS error due to browser's same origin policy. To get around this, you need to tell your browser to enable your client and your server to share resources while being of different origins. In other words, you need to enable cross-origin resource sharing or CORS in your application.
The only way of resolving a CORS failure is to make sure your server sends the correct response headers.
CORS issue occurs in web application if your backend server (your service) is running on a different domain and it is not configured properly. Note: Even if your backend server is running on a localhost with a different port it is treated as a different domain.
Cross-Origin Resource Sharing (CORS) errors occur when a server doesn't return the HTTP headers required by the CORS standard. To resolve a CORS error from an API Gateway REST API or HTTP API, you must reconfigure the API to meet the CORS standard.
You can use this if you want a quick temporary solution.
const url = 'https://cors-anywhere.herokuapp.com/http://localhost:3000/api/countries';
The CORS is mostly a backend issue. You can solve it on Node.js with a code such as:
var express = require('express');
var app = express();
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
But if you want to solve it in frontend, you may use this kind of code in Angular. Put this code into a proxy.conf.json (but beware, a trailing slash is enough to make it not to work):
{
"/api/*": { <-- you may change this for /api/country
"target": "http://localhost:3000",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}
The following in package.json:
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.conf.json",
...
}
And add the proxy config in angular.json:
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "event:build",
"proxyConfig": "proxy.conf.json" <-- this line
},...
Start it with npm start
.
It should work in your case, but in other cases (not in prod of course), I find it easier to use temporarily an extension for Chrome or Firefox. Also I found that because of some restriction it may not work in Chromium and Chrome Canary.
Additionally with React the following code may help:
const proxy = require("http-proxy-middleware");
module.exports = app => {
app.use(
"/api", <-- here again, make sure it fits your needs or it won't work
proxy({
target: "http://localhost:3000",
changeOrigin: true
})
);
};
Try using ng serve --port 3000 . The CORS is mostly backend issue. Since react starts it's server in localhost:3000 you were able to consume it, since angular starts in localhost:4200 you got the cors issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With