Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6 HttpClient - Issues with CORS

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.

like image 269
Sola Oderinde Avatar asked Jan 10 '19 00:01

Sola Oderinde


People also ask

How do you fix the CORS issue in Angular 6?

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.

How do you fix CORS error on client side?

The only way of resolving a CORS failure is to make sure your server sends the correct response headers.

What is CORS issue in Angular?

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.

How do you fix a CORS error in front end?

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.


3 Answers

You can use this if you want a quick temporary solution.

const url = 'https://cors-anywhere.herokuapp.com/http://localhost:3000/api/countries';
like image 111
westdabestdb Avatar answered Oct 18 '22 20:10

westdabestdb


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
    })
  );
};
like image 21
Vince Avatar answered Oct 18 '22 22:10

Vince


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.

like image 22
Arokia Lijas Avatar answered Oct 18 '22 22:10

Arokia Lijas