How can we apply CORS on an express application [duplicate] - javascript

I'm trying to send files to my server with a post request, but when it sends it causes the error:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers.
So I googled the error and added the headers:
$http.post($rootScope.URL, {params: arguments}, {headers: {
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Methods" : "GET,POST,PUT,DELETE,OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
}
Then I get the error:
Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers
So I googled that and the only similar question I could find was provided a half answer then closed as off topic. What headers am I supposed to add/remove?

I had the same problem. In the jQuery documentation I found:
For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain will trigger the browser to send a preflight OPTIONS request to the server.
So though the server allows cross origin request but does not allow Access-Control-Allow-Headers , it will throw errors. By default angular content type is application/json, which is trying to send a OPTION request. Try to overwrite angular default header or allow Access-Control-Allow-Headers in server end. Here is an angular sample:
$http.post(url, data, {
headers : {
'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
}
});

The server (that the POST request is sent to) needs to include the Access-Control-Allow-Headers header (etc) in its response. Putting them in your request from the client has no effect. You should remove the 'Access-Control-Allow-...' headers from your POST request.
This is because it is up to the server to specify that it accepts cross-origin requests (and that it permits the Content-Type request header, and so on) – the client cannot decide for itself that a given server should allow CORS.
The requestor (web browser) may 'preflight' test what the server's Same Origin Policy is by sending an 'OPTIONS' request (ie not the 'POST' or 'GET' request you intend). If the response to the 'OPTIONS' request contains 'Access-Control-Allow-...' headers that permit the headers, origin, or methods your request is using, then the requester/browser will send your 'POST' or 'GET' request.
(obscure note:) The Access-Control-Allow-... have the value '' rather than listing the specific origin, headers, or methods allowed. However, and old Android WebView client I was using didn't honor the '' wildcard and needed the specific headers listed in the Access-Control-Allow-Headers header in the response to the OPTIONS request.

If that helps anyone, (even if this is kind of poor as we must only allow this for dev purpose) here is a Java solution as I encountered the same issue.
[Edit] Do not use the wild card * as it is a bad solution, use localhost if you really need to have something working locally.
public class SimpleCORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "my-authorized-proxy-or-domain");
response.setHeader("Access-Control-Allow-Methods", "POST, GET");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}

You can activate the proper header in PHP with this:
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, X-Requested-With");

The server (that the POST request is sent to) needs to include the Content-Type header in its response.
Here's a list of typical headers to include, including one custom "X_ACCESS_TOKEN" header:
"X-ACCESS_TOKEN", "Access-Control-Allow-Origin", "Authorization", "Origin", "x-requested-with", "Content-Type", "Content-Range", "Content-Disposition", "Content-Description"
That's what your http server guy needs to configure for the web server that you're sending your requests to.
You may also want to ask your server guy to expose the "Content-Length" header.
He'll recognize this as a Cross-Origin Resource Sharing (CORS) request and should understand the implications of making those server configurations.
For details see:
http://www.w3.org/TR/cors/
http://enable-cors.org/

The following works for me with nodejs:
xServer.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", 'http://localhost:8080');
res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Accept');
next();
});

If you are using localhost and PHP set to this to solve the issue:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type');
From your front-end use:
{headers: {"Content-Type": "application/json"}}
and boom no more issues from localhost!

In Asp Net Core, to quickly get it working for development; in Startup.cs, Configure method add
app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

The headers you are trying to set are response headers. They have to be provided, in the response, by the server you are making the request to.
They have no place being set on the client. It would be pointless having a means to grant permissions if they could be granted by the site that wanted permission instead of the site that owned the data.

If anyone experiences this problem with an express server, add the following middleware
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});

if you testing some javascript requests for ionic2 or angularjs 2 , in your chrome on pc or mac , then be sure that you install CORS plugin for chrome browser to allow cross origin .
mayba get requests will work without needing that , but post and puts and delete will need you to install cors plugin for testing to go without problems , that definitley not cool , but i do not know how people do it without CORS plugin .
and also be sure the json response is not returning 400 by some json status

this is backend problem. if use sails api on backend change cors.js and add your filed here
module.exports.cors = {
allRoutes: true,
origin: '*',
credentials: true,
methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
headers: 'Origin, X-Requested-With, Content-Type, Accept, Engaged-Auth-Token'
};

In my case, I'm receiving several parameters as #HeaderParam into a web service method.
These parameters MUST be declared in your CORS filter that way:
#Provider
public class CORSFilter implements ContainerResponseFilter {
#Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
MultivaluedMap<String, Object> headers = responseContext.getHeaders();
headers.add("Access-Control-Allow-Origin", "*");
...
headers.add("Access-Control-Allow-Headers",
/*
* name of the #HeaderParam("name") must be declared here (raw String):
*/
"name", ...);
headers.add("Access-Control-Allow-Credentials", "true");
headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
}

Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers error
means that Access-Control-Allow-Origin field of HTTP header is not handled or allowed by response. Remove Access-Control-Allow-Origin field from the request header.

For me, Added the following to my server's web.config file:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="https://other.domain.com" />
<add name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS,PUT,DELETE" />
<add name="Access-Control-Allow-Headers" value="Content-Type,X-Requested-With" />
</customHeaders>
</httpProtocol>
<system.webServer>

For me I had wildcard "*" Access-Control-Allow-Headers in web.config:
<add name="Access-Control-Allow-Headers" value="*" />
This solution works for most navigators but not for Safari or IE
It turned out the solution was to add manually all the custom header to the web.config:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="https://somedomain.com" />
<add name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS,PUT,DELETE" />
<add name="Access-Control-Allow-Headers" value="custom-header1, custome-header2, custome-header3" />
</customHeaders>
</httpProtocol>
<system.webServer>

Related

Response to preflight request doesn't pass access control check NodeJS/Heroku/Express

I'm using an Express app on Heroku. I try to make a RESTful request to it from another NodeJS app.
Here's a snippet from the Heroku app, called app.js:
var express= require("express");
app.get("/results",function(req,res){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
});
And here's a snippet from an app I run locally, local-app.js:
var request= require("superagent");
var req= request.get("http://url-to-app-js.com?query=1").set(
"Access-Control-Allow-Origin", "http://url-to-app-js.com",
"Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS",
"Access-Control-Allow-Headers", "Content-Type, Authorization, Content-Length, X-Requested-With"
);
req.end(function(err,res){
// do things
});
When I run local-app.js, I got this error in my browser console: esponse to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
I know that I could run the browser, Chromium, with certain security settings turned off, but I need to be able to run this without doing so.
What am I doing wrong? How do I fix it?
Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers are response headers. They shouldn't appear in the request at all.
By adding non-standard headers you make the request a preflighted request instead of a simple request. (You might be doing something else that makes it a preflighted request, but the extra headers definitely do not help).
A preflighted request sends a OPTIONS request to find out if it is allowed by CORS before making the request (GET in this case) you actually want to make.
You are only setting the CORS response headers when you receive a GET request. Since you don't respond with them to the OPTIONS request, the browser refuses to make the GET request.

$http Cross domain access issue exists in header

A request is sent through Angularjs $http with JSON data to my REST service. When the response is returned, required headers are set as following,
Response.ok()
.entity(emp)
.headers.add("Access-Control-Allow-Origin", "*")
.headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.allow("OPTIONS").build();
But when I send a post request without data,
$http.post('localhost:8000/employer/register')
it is successful. With data, it fails.
$http({method: 'post', url:serverUrl, data:{name:'abc'}, headers:{'Content-Type':'application/json'} });
This is my Rest service
#Path("/register")
public class EmpService{
#Get
#Path("test")
#Produces
public String test(){
return "works";
}
#Post
#Consumes(MediaType.APPLICATION_JSON)
public Response addEmp(Emp emp){
return Response.ok()
.entity(emp)
.headers.add("Access-Control-Allow-Origin", "*")
.headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.allow("OPTIONS").build();
Browser console is as following.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8081/employer/register (Reason: CORS header 'Access-Control-Allow-Origin' missing).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8081/employer/register (Reason: CORS request failed).
UPDATE: I found that service is not invoked as no Sys.out.println gives any logs.
Anyone know where the problem is?
Don't add the headers inside the resource method. Why? The preflight is an OPTIONS request, which is the "pre"-request to get the access control headers. And you don't have an OPTIONS method. The browser will not call the #POST method to get the access control headers. For this reason, you should be using a filter instead, and set the headers there.
Try this.May be your api route of server not allowed headers data that may be caused problem
$http.post(url:serverUrl, data:{name:'abc'} } );
Maybe you should be sending a header not allowed by the server.
Try this:
headers.add("Access-Control-Allow-Headers",
"Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, otherCustomHeader");

How to enable CORS in OrientDb server-config.xml

Am using OrientDb database, I have setup Orientdb server in my system, OrientDb has exposed Http Api's. So am trying to call API http://localhost:2480/query/test2/sql/select * from OUser , From javascript using AJAX call, I have set headers
Accept : "application/json;charset=utf-8",
"Access-Control-Allow-Origin":"*",
'Access-Control-Allow-Methods': 'POST, GET, DELETE, HEAD, OPTION',
'Access-Control-Allow-Headers': 'Origin, x-requested-with, content-type, accept',
'Access-Control-Allow-Credentials': true
And also I enabled CROS in orientdb-server-config.xml
parameter name="network.http.additionalResponseHeaders" value="Access-Control-Allow-Origin:*;Access-Control-Allow-Credentials: true;Access-Control-Allow-Headers: Origin, x-requested-with, content-type, accept;Access-Control-Allow-Methods: POST, GET, DELETE, HEAD, OPTION"
parameter value="utf-8" name="network.http.charset"
Still am getting
Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.
How to enable CORS in OrientDb server?
Access-Control-Allow-* are response headers, not request headers. They are used so the server can give your JS permission to read its data (not so that your JS can give itself permission to read the server's data).
You are setting them as custom request headers (in your JavaScript).
The CORS spec requires that you have explicit permission to set custom request headers, and you don't have permission from the server to set those (and why would you? They are nonsense.).
Don't set them in the JS.

Mandrill XMLHttpRequest Error - invalid Access-Control-Allow-Origin headers

I have an app on Heroku at http://random-name.herokuapp.com that sends emails with Mandrill. However, regardless of whether I'm running the app locally at localhost:5000 or remotely on Heroku, I throw the following error when trying to send emails:
XMLHttpRequest cannot load
https://mandrillapp.com/api/1.0/messages/send.json. Response to
preflight request doesn't pass access control check: A wildcard '*'
cannot be used in the 'Access-Control-Allow-Origin' header when the
credentials flag is true. Origin 'http://random-name.herokuapp.com' is
therefore not allowed access.
There's a lot of documentation on Stack Overflow about this error (see CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true), and consequently, I set my express headers to the following:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:5000 http://random-name.herokuapp.com");
res.header('Access-Control-Allow-Credentials', true);
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
However, this doesn't seem to solve the issue. I couldn't find anything useful in Mandrill's documentation either. I'm guessing I'm specifying the headers incorrectly, or perhaps they aren't even being used. Any ideas?
Access-Control-Allow-Origin takes a single value, not a space separated list.
You need to return whatever the client sends in the Origin request header (test to make sure that is an acceptable origin to you first though!).

'Request header field Authorization is not allowed' error - Tastypie

I am getting the following error while using ApiKeyAuthentication for my Tastypie resources when I try to do an HTTP request using AJAX and Tastypie:
XMLHttpRequest cannot load http://domain.com/api/v1/item/?format=json&username=popo&api_key=b83d21e2f8bd4952a53d0ce12a2314c0ffa031b1. Request header field Authorization is not allowed by Access-Control-Allow-Headers.
Any ideas on how to solve this?
Here are the request headers from Chrome:
Request Headersview source
Accept:*/*
Accept-Charset:
ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:
origin, authorization, access-control-allow-origin, accept, access-control-allow-headers
Access-Control-Request-Method:
GET
Here are the response headers from Chrome:
Response Headersview source
Access-Control-Allow-Headers:
Origin,Content-Type,Accept,Authorization
Access-Control-Allow-Methods:
POST,GET,OPTIONS,PUT,DELETE
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:0
Content-Type:
text/html; charset=utf-8
Date:Fri, 11 May 2012 21:38:35 GMT
Server:nginx
As you can see, they both have headers for Authorization, yet authorization does not work.
Here is the django middleware that I am using to edit the response headers:
https://gist.github.com/1164697
Edit:
I figured out the problem. I was trying to connect to www.domain.com, and it only accepts domain.com
Antyrat's answer is not complete.
You have to specify which headers your server allows; in your case Authorization.
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization
Although I upvoted the answer of #Manuel Bitto,
I would like to post another answer which contains a complete Cors Filter that works for me with Apache tomcat 5.x:
public class CorsFilter implements Filter {
public CorsFilter() { }
public void init(FilterConfig fConfig) throws ServletException { }
public void destroy() { }
public void doFilter(
ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse)response;
httpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
httpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS, DELETE");
httpServletResponse.addHeader("Access-Control-Allow-Headers", "Authorization");
chain.doFilter(request, response);
}
}
I would suggest to specifically pay attention to the addition of OPTIONS to to the "Access-Control-Allow-Methods" header values.
The reason for doing that is that according to the explanation provided here by Mozilla,
if your request (let's say POST) contains a special header, or content type (and this is my case), then the XMLHttpRequest object will generate an additional OPTIONS call, which you need to address in your code.
I hope this helps.
This happens because of Same origin policy.
You need to make AJAX call from same domain where request goes. Or make server-side changes, allowing requests from external domains.
To resolve this you need to make changes in headers at http://domain.com by allowing your external domain in headers:
Access-Control-Allow-Origin: *
Read more
The problem was that www.domain.com was seen as different than domain.com.
domain.com worked, but when I used www.domain.com, it detected me as doing requests from a different domain
I know this question is older.
But today I ran into same cors issue after adding owin. After number of search on google and trying various solutions. I solved cors issue by adding below
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
For more details please follow the below links. Thanks.
[http://benfoster.io/blog/aspnet-webapi-cors]

Categories