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");
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.
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.
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
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.
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()
});
}
}
You may use Angular CLI proxy tooling for this purpose.
"/api/xxxxxxx" : {
"target" : "http://www.api.com/xxxxxxx",
"secure" : false,
"logLevel" : "debug",
"changeOrigin": true
}
ng serve --proxy-config proxy.config.json
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