Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4 http CORS No 'Access-Control-Allow-Origin' with a java servlet

I'm trying to do a http.post but chrome is showing the following error:

No Access-Control-Allow-Origin.

My Angular function is:

onSubmit(event: Event) {
  event.preventDefault();
    this.leerDatos()
    .subscribe(res => {
      //datos = res.json();
      console.log("Data send");
    }, error => {
          console.log(error.json());
      });



  }

  leerDatos(): Observable<any> {
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });

    return this.http.post(`http://localhost:8080/LegoRepositoryVincle/CoreServlet`, { name: "bob" }, options)
                    //.map(this.extractData)
                    //.catch(this.handleError);
  }

And my servlet doPost method includes:

response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.addHeader("Access-Control-Allow-Origin","http://localhost:4200");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods","GET,POST");
response.addHeader("Access-Control-Allow-Headers","X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept, Cache-Control, Pragma");
like image 210
Nau Parejaa Escamilla Avatar asked Jul 05 '17 11:07

Nau Parejaa Escamilla


People also ask

Why can't I make CORS requests in Angular 2?

Unfortunately, that's not an Angular2 error, that's an error your browser is running into (i.e. outside of your app). That CORS header will have to be added to that endpoint on the server before you can make ANY requests.

Why can't I see the response to my angular request?

This should open our Angular application in the browser. Visit http://localhost:8000 in your browser, and check the console. You'll find a CORS error thrown by the browser. CORS error in Angular. Also, the browser has blocked your request, and you won't be able to see the response of the request.

Why is origin not allowed access to localhost?

Origin 'http://localhost:8080' is therefore not allowed access. This a problem with the CORS configuration on the server. It is not clear what server are you using, but if you are using Node+express you can solve it with the following code

How to fix angular CLI not responding to Cors header?

One way to fix it is by enabling proper CORS headers request on the server-side. Another way is to configure Angular CLI proxy. Note: The correct approach or solution is to configure the backend server, but that may not always be feasible.


2 Answers

If you still want to use CORS while developing you can solve this kind of issue using angular/cli --proxy-config.

Essentially, if you want to make requests to a remote machine having, for example, nginx web server running, you perform all your calls to your very same application, e.g. localhost:4200 (default in angular/cli). Then you redirect those responses to your server using --proxy-config.

Let's suppose your server's api have all the /api prefix entrypoint. You need to create a file called proxy.config.json in the root of your project and configure it like:

{
    "/api" : {
        "target" : "http://xx.xxx.xxx.xx", // Your remote address
        "secure" : false,
        "logLevel" : "debug", // Making Debug Logs in console
        "changeOrigin": true
    }
}

And then, all your http requests will point to localhost:4200/api/.

Finally, you should be done by running ng server --proxy-config proxy.config.json.

If you notice that some headers are missing in the request, add them from your web server or edit your http.service.ts to append those like in this example:

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { isNull } from 'lodash';

@Injectable()
export class HttpClientService {

  private _host: string;
  private _authToken: string;
  private _options: RequestOptions = null;

  constructor(private _http: Http, private _config: AppConfig, private _localStorageService: LocalStorageService) {
      this._host = ''; // Your Host here, get it from a configuration file
      this._authToken = ''; // Your token here, get it from API
  }

  /**
   * @returns {RequestOptions}
   */
   createAuthorizationHeader(): RequestOptions {
      // Just checking is this._options is null using lodash
      if (isNull(this._options)) {
        const headers = new Headers();
        headers.append('Content-Type', 'application/json; charset=utf-8');
        headers.append('Authorization', this._authToken);
        this._options = new RequestOptions({headers: headers});
      }
      return this._options;
   }

   /**
    * @param url {string}
    * @param data {Object}
    * @return {Observable<any>}
    */
    get(url?: string, data?: Object): Observable<any> {
      const options = this.createAuthorizationHeader();
      return this._http.get(this._host + url, options);
    }

   /**
    * @param url {string}
    * @param data {Object}
    * @return {Observable<any>}
    */
    post(url?: string, data?: Object): Observable<any> {
      const body = JSON.stringify(data);
      const options = this.createAuthorizationHeader();
      return this._http.post(this._host + url, body, options);
    }

}

So, you would perform all of your api calls through this service like

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpClientService } from './http.service.ts';

export class TestComponent implements OnInit {

  _observable: Observable<any> = null;

  constructor(private _http: HttpClientService) { }

  ngOnInit() {
      this._observable = this _http.get('test/')
                .map((response: Response) => console.log(response.json()));
  }

}

Angular 5 Update:

In app.module.ts now you need to replace import { HttpModule } from '@angular/http'; with import { HttpClientModule } from '@angular/common/http';.

The service changes a bit to:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { isNull, isUndefined } from 'lodash';

@Injectable()
export class HttpClientService {

  private _host: string;
  private _authToken: string;
  private __headers: HttpHeaders;

  constructor(private _http: HttpClient, private _config: AppConfig, private _localStorageService: LocalStorageService) {
      this._host = ''; // Your Host here, get it from a configuration file
      this._authToken = ''; // Your token here, get it from API
  }

  /**
   * @returns {HttpHeaders}
   */
   createAuthorizationHeader(): HttpHeaders {
      // Just checking is this._options is null using lodash
      if (isNull(this.__headers)) {
        const headers = new HttpHeaders()
           .set('Content-Type', 'application/json; charset=utf-8')
           .set('Authorization', this. _authToken || '');
        this.__headers= new RequestOptions({headers: headers});
      }

      return this.__headers;
   }

   /**
    * @param url {string}
    * @param data {Object}
    * @return {Observable<any>}
    */
    get(url?: string, data?: Object): Observable<any> {
      const options = this.createAuthorizationHeader();
      return this._http.get(this._host + url, {
          headers : this.createAuthorizationHeader()
      });
    }

   /**
    * @param url {string}
    * @param data {Object}
    * @return {Observable<any>}
    */
    post(url?: string, data?: Object): Observable<any> {
      const body = JSON.stringify(data);
      const options = this.createAuthorizationHeader();
      return this._http.post(this._host + url, body, {
          headers : this.createAuthorizationHeader()
      });
    }
}
like image 192
AndreaM16 Avatar answered Oct 05 '22 23:10

AndreaM16


You may use Angular CLI proxy tooling for this purpose.

  • 1. you create a file proxy.config.json at the root of your project
  • 2. you map your API URLs to target URLs using this syntax
 "/api/xxxxxxx" : {
        "target" : "http://www.api.com/xxxxxxx", 
        "secure" : false,
        "logLevel" : "debug",
        "changeOrigin": true
    }
  • 3. Serve your application using
ng serve --proxy-config proxy.config.json
like image 42
Kodjo Tchioffo Avatar answered Oct 05 '22 22:10

Kodjo Tchioffo