I am having a weird issue where my client side request is telling me I have no 'Access-Control-Allow-Origin' present when making an HTTP POST request to a java servlet I have hosted and live. I have made sure to add the necessary headers in my response to clear up CORS requests issues but it does not seem to be recognizing the headers.
Here is my angular $http.post request I am making from the client side:
var parameter = JSON.stringify(details);
var req = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
data: parameter
}
$http.post(localurl, req).
then(function(response) {
});
Here is the error I am getting from chrome:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8081' is therefore not allowed access.
Here is the beginning of my java servlet doPost function:
#Override
public void doPost(HttpServletRequest req, HttpServletResponse res) {
res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
res.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
I have been searching various stackoverflow questions and those response headers I am setting in my servlet should clear up the CORS requests issues but it does not seem to be recognizing the response headers I am setting at the beginning of the doPost function. Any and all help is very appreciated. Thanks in advance.
The problem is on your back-end, if yours is nodejs, should be like this way to allow Access-Control-Allow-Origin:
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
Related
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();
}
}
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. How best to handle the OPTIONS requests for all endpoints on your server is a question for Java experts (which I am not).
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.
Getting error while making post request from Angular app to servlet doPost method.
Angular application make 2 request 1 for doGet method and other doPost method.
In doGet method i added following heders as follows
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setHeader("Access-Control-Allow-Methods", "GET");
resp.setHeader("Access-Control-Max-Age", "3600");
resp.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
and solved my CORS problem for GET call.
but doPost method give CORS error even i added same header in doPost method.
angular console shows
Access to XMLHttpRequest at 'http://localhost:8080/server/config' 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.
Server is written in servlet and running on port 8080.
Front end is written in Angular 8 and running on port 4200.
How to solve CORS error for post call...
Thanks..
In your code, only allow GET method. Update your code like:
resp.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS,DELETE");
I'm using spring boot service for backend and and angular 6 for frontend.
In spring boot i enabled cors using.
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/interview/**").allowedOrigins("*");
}
and i'm using intercepter for each service.
in frontend calling service:
headers = new Headers();
constructor(private http: Http, private logger: MLogger) {
this.headers.set("Access-Control-Allow-Origin", "*");
this.headers.set( 'Content-Type', 'application/json',);
this.headers.set( 'Accept', '*');
this.headers.set( 'sessionId', DataService.sessionId);
}
private options = new RequestOptions({ headers: this.headers});
interviewCommand: InterviewCommand;
getInterviewDetails(data: any): Promise<any> {
const serviceURL = environment.startInterviewURL;
return this.http
.post(serviceURL,data, this.options)
.toPromise()
.then(
interviewCommand => {
//doing some stuff
}
})
.catch(this.handleInterviewCommandError);
}
I'm getting below exception if using intercepter. Without using interepter i'm not getting cors error..
Failed to load http://localhost:7070/example/myservice: Request header
field Access-Control-Allow-Origin is not allowed by
Access-Control-Allow-Headers in preflight response.
In my intercepter i added below thing:
if (request.getMethod().equals("OPTIONS")) {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Origin-Methods", "GET, POST, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Range, Content-Disposition, Content-Description,Origin, X-Requested-With");
response.setHeader("Access-Control-Expose-Headers", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Max-Age", "4800");
}
Got Answer...
Removed this.headers.set("Access-Control-Allow-Origin", "*") from your
frontend
and
added in backend in intercepter response..
response.setHeader("Access-Control-Allow-Headers",
"Authorization,Content-Type, Content-Range, Content-Disposition,
Content-Description,Origin, X-Requested-With, sessionId");
response.setHeader("Access-Control-Allow-Origin", "*");
When you start playing around with custom request headers you will get a CORS preflight. This is a request that uses the HTTP OPTIONS verb and includes several headers, one of which being Access-Control-Request-Headers listing the headers the client wants to include in the request.
You need to reply to that CORS preflight with the appropriate CORS headers to make this work. One of which is indeed Access-Control-Allow-Headers. That header needs to contain the same values the Access-Control-Request-Headers header contained (or more).
https://fetch.spec.whatwg.org/#http-cors-protocol explains this setup in more detail.
solution is here
I am trying to call servlet using ajax on click event. And from that servlet I am calling google auth end point. I tried set header to the servlet I am calling but I an not able to get rid of this error
XMLHttpRequest cannot load
https://accounts.google.com/o/oauth2/auth?client_id=2536-a…nid%20profile%20email&state=F1BFD3804&display=popup.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8080' is therefore not allowed
access.
Here is the code
$.ajax({
type: "GET",
url: "/url-for-servlet",
dataType: "jsonp",
contentType: 'application/json',
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR)
},
success: function (data) {
alert("yippy");
console.log(data);
}
});
On servlet I added to response
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.addHeader("Access-Control-Max-Age", "3600");
response.addHeader("Access-Control-Allow-Headers", "x-requested-with");
Any idea what I am missing here? Thanks for the help.
This is a standard security restriction : JS cannot make requests to domains other than their own. So you have an application on localhost making Ajax calls to an application on accounts.google.com - not allowed by default.
See this question
AJAX usually doesn't allow to call other domain API from it. It is called CSRF attack. The solution for you is, Post the data to your server servlet and do the action required there in the backend(Servlet).
I want to call my rest web service from ajax. Url for my service is 'https://scv-dev.com/cdcAug/surveys/surveyData'. Iam able to call this service from rest client (firefox browser) but when am trying to call from ajax am getting error.
Ajax call :
$.ajax({
type: "POST",
url: "https://scv-dev.com/cdcAug/surveys/surveyData",
data: JSON.stringify({surveyId:1}),
dataType: "json",
headers: {
Accept: "application/json",
"Access-Control-Allow-Origin": "*"
},
success: function (data) {
alert(1);
},
error: function (jqXHR) {
alert(2);
}
});
Below is code for webs service :
#RequestMapping(value = "/surveyData", method = RequestMethod.POST, headers = "Accept=application/json")
public #ResponseBody
SurveyDataResponse getSurveyData(#RequestBody SurveyResApp surveyResApp,
final HttpServletResponse httpResponse) {
..............
}
You appear to be confused about Access-Control-Allow-Origin: *. That is something the server returns, not something the client sets.
It appears that you have a same-origin access error and looking in the browser error log or diagnosing the returned error codes should tell you what exactly is going on.
You probably need to enable your web service for cross origin access by adding that header Access-Control-Allow-Origin: * to your server response. See here for an example.
I created filter class added below code in that to add "Access-Control-Allow-Methods" in response.
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
response.addHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
response.addHeader("Access-Control-Max-Age", "1728000");