I have a frontend in Angular and the backend is Java EE. The issue I am running into is that the backend is expecting a standard Http request but Angular HttpClient sends XHR. I get this error:
I think the two options I have are
- somehow update the backend to allow CORS access-control-allow-origin which I would have to figure out how to do and assuming that I have the option to make changes to the backend ---OR---
- change the front end to send an Http request and not XHR.
Since I am writing the frontend and can easily manipulate it, this is the option I am shooting for.
Below is the service for sending the Get request:
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Survey } from './survey';
import { HttpErrorHandler, HandleError } from '../http-error-handler.services';
import { environment } from '../../environments/environment';
@Injectable({
providedIn: 'root'
})
export class SurveysDisplayService {
surveysURL=environment.baseUrl 'api/surveys/';
private handleError: HandleError;
constructor(
private http: HttpClient,
httpErrorHandler: HttpErrorHandler) {
this.handleError = httpErrorHandler.createHandleError('DisplayService');
}
//retrieve surveys from server
getSurveys(): Observable<Survey[]>{
return this.http.get<Survey[]>(this.surveysURL)
.pipe(
catchError(this.handleError('getSurveys', []))
);
}
}
and here is the component.ts that uses the service:
import { Component, OnInit } from '@angular/core';
import { Survey } from './survey';
import { SurveysDisplayService } from './surveys-display.service';
@Component({
selector: 'app-survey',
templateUrl: './surveys-display.component.html',
providers:[SurveysDisplayService],
styleUrls: ['./surveys-display.component.css']
})
export class SurveysDisplayComponent implements OnInit {
surveys:Survey[]=[];
constructor(private surveysDisplayService:SurveysDisplayService) { }
ngOnInit(): void {
this.getSurveys();
}
getSurveys(): void {
this.surveysDisplayService.getSurveys()
.subscribe(surveys => (this.surveys=surveys));
}
}
details for my Angular version
CodePudding user response:
Your problem is basically this: you need CORS headers from the server but you can not make it send them. To overcome this you might need a proxy that would do exactly that. I can suggest using HAProxy, here's a snipper from this blog
that does what you need:
listen http-in
mode http
listen *:80
# Add CORS headers when Origin header is present
capture request header origin len 128
http-response add-header Access-Control-Allow-Origin %[capture.req.hdr(0)] if { capture.req.hdr(0) -m found }
rspadd Access-Control-Allow-Headers:\ Origin,\ X-Requested-With,\ Content-Type,\ Accept if { capture.req.hdr(0) -m found }
Or you could use nginx (slightly more complicated to set up), you can find an example configuration here.
CodePudding user response:
somehow update the backend to allow CORS access-control-allow-origin which I would have to figure out how to do and assuming that I have the option to make changes to the backend
You need to do that.
This answer lists a couple of alternatives but if you don't have access to the backend then writing a new backend that acts as a proxy to the existing one is likely to be the only practical one.
change the front end to send an Http request and not XHR.
XHR is an API used to make HTTP requests from JavaScript. It isn't a different kind of request.
If you want to switch to "not XHR" then you are looking at using a regular form submission or link which will load a whole new page and probably make using Angular pointless.
Doing that also requires that you change the backend, this time so it returns a new HTML document.
CodePudding user response:
Access Control Allow Origin - is server side error (you must do one of bellow solutions):
add OPTION type request to your server side
or
use some server (nginx for example) and make front & back works on same domain & port