When trying to issue a POST request in firefox the following error messages come up:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.net/graphql. (Reason: missing token 'content-type' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.net/graphql. (Reason: CORS request did not succeed).
The same request succeeds in Chrome. The request I am sending is:
method: 'POST',
headers:{
'x-client-id': '123',
'content-type': 'application/json; charset=UTF-8'
},
body: JSON.stringify({
query: "query ..."
})
})
.then(res => res.json())
.then(console.log);```
I am issuing this request while on another https origin.
My setup in my code for cors is simply the spring annotation:
```#CrossOrigin(allowedHeaders = {"content-type", "x-client-id"})```
You will need these headers:
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header Content-Type: text/html;
charset=utf-8
at the target in order to allow CORS. If you have no access to the remote stuff, then use your server as a proxy and send the request from there, return the response to your browser.
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.
I´m trying to connect a Angular web to Java backend. For do this i use different endpoints. Return
has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource.
I try adding proxy.conf.json like this in angular
{
"/URL/*": {
"target": "ENDPOINT",
"secure": false,
"changeOrigin": true
}
}
I try too modify .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
No works.
So: What´s is the properly way to abble CORS in angular endpoints?
UPDATE
httpOptions in angular
const httpOptions = {
headers: new HttpHeaders({
Authorization: "Token " + localStorage.getItem("token")
})
};
Welcome to the shitty world of modern Browsers :-)
If you use a Authorization header your Browser will perform a preflight request to check if your Browser has not been messed with via your Website and check the response. In particular, he will check if Access-Control-Allow-Origin is valid and for requests containing a Authorization header that means that a wildcard (*) is not valid! To make a Backend CORS-able you must allow the Origin of the request as a explicit Access-Control-Allow-Origin which leads many Backend developers to simply take the value of the Origin request header and put it into the Access-Control-Allow-Origin response header.
So when your Browser requests the Backend during a preflight, your Backend has to respond similar to
Access-Control-Allow-Origin: <The requesting Origin must be included>
Access-Control-Allow-Headers: origin, x-requested-with, content-type, authorization
Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
More on this can be found on Mozilla's page on CORS: https://developer.mozilla.org/de/docs/Web/HTTP/CORS
Here is my web.xml file:
https://pastebin.com/SSMu7qKb
And I try to send a GET request from my application with the following headers
'Content-Type': 'application/json',
'Authorization': "Basic ZGVtbzpkZW1v",
'Cache-Control': "no-cache"
to http://localhost:8080/engine-rest/user
I traced my request using Postman. Here are the headers in the request:
[{“key”:“Access-Control-Request-Method”,“value”:“GET”,“description”:""},
{“key”:“Origin”,“value”:“http://evil.com/",“description”:"”},
{“key”:“X-DevTools-Emulate-Network-Conditions-Client
Id”,“value”:“6B279966ED84E2BE5D06B4F083711A81”,“description”:""},
,{“key”:“Access-Control-Request-Headers”,“value”:“authorization,cache-control,content-type”,“description”:""},{“key”:“Accept”,“value”:"/",“description”:""},
{“key”:“Accept-Encoding”,“value”:“gzip, deflate, br”,“description”:""}
,{“key”:“Accept-Language”,“value”:“en-US,en;q=0.9”,“description”:""},
{“key”:“Authorization”,“value”:“Basic ZGVtbzpkZW1v”,“description”:""}]
If I add an Authorisation header in Postman to the ones I have above, I can send the request. Otherwise I get the error code 401 (Unauthorized). But OPTIONS shouldn’t ask for authorisation.
Here is the code for the filter:
https://github.com/quickhack/tomcat/blob/master/src/main/java/org/apache/catalina/filters/CorsFilter.java
The CorsFilter is the first filter in my web.xml file and in CorsFilter.java if the request is identified as Preflight it will not pass go to the next filter(see handlePreflightCORS method). So normally when I have an Preflight request it should not check for authorisation. So why do I get an error 401 ?
I am new to Angular2. I have to create new Angular application and Need to use services from Liferay server.
But When I call the Service using below code, it is giving Cors error.
var headers = new Headers();
headers.append('Access-Control-Allow-Origin', '*');
headers.append("Content-Type", "application/x-www-form-urlencoded");
let params: URLSearchParams = new URLSearchParams();
this.http.get(localStorage.getItem('domainName')+'/service-name', {headers: headers})
.subscribe(response => {
// login successful if there's a jwt token in the response
console.log('Response'+response.json());
});
My backend method is GET and I have added Cors filter property in my /webapps/Root/web.xml file
BUt in browser console it is giving below error:
XMLHttpRequest cannot load http://localhost:9080/service-name. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 401.
This error comes up when the backend's response does not have the necessary Access-Control-Allow-Origin header. Please double check that the backend's headers are properly configured. Also, the frontend's request does not have to have the Access-Control-Allow-Origin header ever.
I set CORS to allow few custom headers. Below is the Response Header -
Response Headers { "Date": "Mon, 14 Mar 2016 10:11:59 GMT",
"Server": "Apache-Coyote/1.1", "Transfer-Encoding": "chunked",
"Access-Control-Max-Age": "3600", "Access-Control-Allow-Methods":
"POST, GET, OPTIONS, DELETE, PUT", "Content-Type":
"application/json", "Access-Control-Allow-Origin":
"*",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Headers": "X-Requested-With, Authorization,
Content-Type, Authorization_Code, User_Credentials,
Client_Credentials" }
Above response header should mean that API can be consumed from all the origins with following headers: Authorization, Content-Type, Authorization_Code, User_Credentials, Client_Credentials
I can pass all headers and consume APIs from all origins.
PROBLEM -
Requests with Authorization APIs are not being allowed. Authorization is a header with which Oauth token is passed like this - Authorizatio = Bearer ct45tg4g3rf3rfr5freg34gerfgr3gf (Bearer token).
corsclient.js:609 OPTIONS http://54.200.113.97:8080/supafit-api/users
sendRequest # corsclient.js:609(anonymous function) #
corsclient.js:647b.event.dispatch # jquery-1.9.1.min.js:3v.handle #
jquery-1.9.1.min.js:3
/client#?client_method=GET&client_credentials=false&client_headers=Authoriz…nable=true&server_status=200&server_credentials=false&server_tabs=remote:1
XMLHttpRequest cannot load
http://54.200.113.97:8080/supafit-api/users. Response to preflight
request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://client.cors-api.appspot.com' is therefore not
allowed access. The response had HTTP status code 401.
EDIT:
Here is the Rest Client test of that API -
Response Header -
Server: Apache-Coyote/1.1
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: http://client.cors-api.appspot.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Access-Control-Max-Age: 3600
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Headers: Authorization
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Headers: Authorization_Code
Access-Control-Allow-Headers: User_Credentials
Access-Control-Allow-Headers: Client_Credentials
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 14 Mar 2016 11:19:42 GMT Raw JSON
JSON Response Body -
{ "id":78, "userId":"3465434567", "coachId":null,
"name":"XDCDSC", "dob":null, "email":"puneetpandey37#gmail.com",
"imageURL":"https://lh5.googleusercontent.com/-TcTQeitAvag/AAAAAAAAAAI/AAA/4pamurzO1a4/photo.jpg",
"gender":null, "userPhysic":null, "userTypeId":1,
"dietitanId":null, "alternateEmailId":null,
"yearsOfExperience":null, "lastExperience":null,
"languagesKnown":null, "aboutYourself":null,
"coreCompetence":null, "fieldOfWork":null, "userAddresses":[
{
"id":1,
"userId":78,
"locationId":1,
"address":"EC",
"landmark":"Near BN",
"phoneNumber":null,
"addressType":"Home"
} ], "phoneNumbers":[
] }
The response had HTTP status code 401.
Your server needs authentification for the Preflight Request, but the client removes credentials as CORS specification says:
Otherwise, make a preflight request. Fetch the request URL from origin source origin using referrer source as override referrer source with the manual redirect flag and the block cookies flag set, using the method OPTIONS, and with the following additional constraints:
Include an Access-Control-Request-Method header with as header field value the request method (even when that is a simple method).
If author request headers is not empty include an Access-Control-Request-Headers header with as header field value a comma-separated list of the header field names from author request headers in lexicographical order, each converted to ASCII lowercase (even when one or more are a simple header).
Exclude the author request headers.
Exclude user credentials.
Exclude the request entity body.
You have to change your server, to allow anonymous access of Preflight Request.