I have issue in my application. I have various REST enpoints which are working fine. But now I want to send POST request with body. I already have 2 endpoints for POST method, but data are send using PathParam.
I created new endpoint, but when I send request I am getting CORS error. When I use the same endpoint without body in request everything is okay but of course at backend side I do not get any data from frontend (I have breakpoint inside method).
this is how I send request from my angular application:
post(requestUrl: string, body?: any): Observable<any> {
return this.httpClient.post<any>(this.API_URL requestUrl, {password: 'test'});
}
After sending request I got:
Access to XMLHttpRequest at 'http://localhost:8080/...' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
If I send request like this (without body) this endpoint works fine:
post(requestUrl: string, body?: any): Observable<any> {
return this.httpClient.post<any>(this.API_URL requestUrl);
}
At backend side I have added settings for CORS:
return Response.ok(object).header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.allow("OPTIONS").build();
When I am sending request from Insomnia everything is ok - I can send body and I am getting sent data on backend.
Should I somehow set request headers at frontend side?
Here is my AdminApiController class:
@Path("/admin")
@RequestScoped
public class AdminApiController extends BaseApiController {
@Inject
private AdminAssembler adminAssembler;
@POST
@Path("/login")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response login(LoginRequest request) {
return Response.ok(adminAssembler.login(request))
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.header("Access-Control-Allow-Headers", "Content-Type")
.allow("OPTIONS").build();
}
}
CodePudding user response:
When your angular application sends a JSON payload in a POST request, it probably adds the header Content-Type: application/json
. This header classifies the POST request as a "non-simple" request (that is, a request that cannot result out of an HTML <form>
element without additional Javascript). Such "non-simple" requests cause to browser to make a preceding preflight request, that is an OPTIONS request with headers
Origin: http://localhost:4200
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
to which the server must respond with an Access-Control-Allow-Origin
header and Access-Control-Allow-Headers: Content-Type
. If it does not, the browser will not make the POST request and show an error like you observed.
Your Java code covers only @POST
, not @OPTIONS
, that's why the server does not respond to the preflight request with the necessary headers.
CodePudding user response:
You need to define your httpOptions. Try this.
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
post(requestUrl: string, body?: any): Observable<any> {
this.httpClient.post<any>(this.API_URL requestUrl, {password: 'test'}, this.httpOptions)
}
Let me know if it worked for you.