CORS - Access-Control-Allow-Origin issue - javascript

I have an AngularJS web application with a RESTful Jersey Api as Backend.
I'm making a call to this API
function Create(user) {
return $http.post('http://localhost:8080/NobelGrid/api/users/create/', user).then(handleSuccess, handleError('Error creating user'));
}
This is the code of the API (POST):
/**
* This API create an user
*
* #param data
* #return
*/
#Path("create")
#POST
#Produces("application/json")
public Response create(String data) {
UserDataConnector connector;
JSONObject response = new JSONObject(data);
User userToCreate = new User(response.getString("surname"), response.getString("name"),
response.getString("mail"), response.getString("username"), response.getString("password"), 0);
try {
connector = new UserDataConnector();
connector.createUser(userToCreate);
} catch (IOException e) {
e.printStackTrace();
}
return Response.status(Response.Status.OK) // 200
.entity(userToCreate)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, X-Codingpedia,Authorization")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT").build();
}
/**
* CORS compatible OPTIONS response
*
* #return
*/
#Path("/create")
#OPTIONS
public Response createOPT() {
System.out.println("Called OPTION for create API");
return Response.status(Response.Status.OK) // 200
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, X-Codingpedia,Authorization")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS").build();
}
I've added an OPTION API for create in order to make that API CORS-compatible. In fact the API works well cause the OPTIONS API is called before the POST one and the user is created in my Database. Anyway on front end side I get this error:
XMLHttpRequest cannot load http://localhost:8080/NobelGrid/api/users/create/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access. The response had HTTP status code 500.
Can anyone please help me?
UPDATE:
stack suggests this question No Access-Control-Allow-Origin header is present on the requested resource as possible duplicate but that solution doesn't work for me cause addHeader(String) is not present in Response Jersey API.
UPDATE 2
I solved the issue using this solution:
http://www.coderanch.com/t/640189/Web-Services/java/Access-Control-Origin-header-present
But I have another error. I will do another question cause I think it's a different argument.
Thanks in advanced!

I solved the issue using this solution:
http://www.coderanch.com/t/640189/Web-Services/java/Access-Control-Origin-header-present
But I have another error.
I will do another question cause I think it's a different argument.

Use CORS NPM and add as a middleware.
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
------------------------- Add this lines in your app.js -------------------------
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');

Related

HTTPS Request : CORS error but I still get data

I'm making HTTPS request to a private API (hosted Itop), I get an response but I get CORS Multiple Origin Not Allow error so my JavaScript program can't use the response content.
I'm supposed to have CORS authorization
The requests are POST, made with fetch, there isn't preflight (OPTIONS) request made before (fetch did them alone for my other GET API request but didn't here)
Also some server response time is long for firefox (~2s) but it don't seems to change anything
It's not allowed to send multiple Access-Control-Allow-Origin headers or multiple origins in one header in the same response. In the comments, you described two same Access-Control-Allow-Origin headers in one response. Even two same origins aren't allowed. Remove one header in the backend code.
firefox is the best browser to identify this issue,
you can fix this issue by following this path.
when you sending a request from frontend,and then response will come from backend. but browser is not allowed to aceess to javascript. this is the cors error.
1.open ur backend, then create a package call CorsFilter.
2. and then create a filter servlet
3. paste this code
CorsFilter
#WebFilter(filterName = "CorsFilter", urlPatterns = "/*")
public class CorsFilter extends HttpFilter {
#Override
protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
String origin = req.getHeader("Origin");
if (origin != null && origin.toLowerCase().contains(getServletContext().getInitParameter("origin"))) {
res.setHeader("Access-Control-Allow-Origin", origin);
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
res.setHeader("Access-Control-Expose-Headers", "Content-Type");
if (req.getMethod().equals("OPTIONS")) {
res.setHeader("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE, HEAD");
}
}
chain.doFilter(req, res);
}
}

How to set access control allow origin in socket io

I am using socket.io and express js. I want to set access control allow origin to the socket connection
I've tried setting the origins property when initializing socket
var io = require('socket.io')(http, {origins: 'http://www.example.com'})
In the image above access control allow origin is set to *. I want to set that to example.com (also note the request method is GET)
In this image however the access control allow origin header is set (also note the request method is POST)
How can I add the access control allow origin header when the request method is GET. Please help
Have you tried:
io.set('origins', 'http://yourdomain.com:80');
Or you can also try server.origins like below:
io.origins((origin, callback) => {
if (origin !== 'https://foo.example.com') {
return callback('origin not allowed', false);
}
callback(null, true);
});
By returning true, you allow the origin. Otherwise, send the error message. Refer docs here
please try below in express main file
// Add headers
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://yourdomain.com:80');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Pass to next layer of middleware
next();
});
In Express you can use like this:
app.all('*(or set for what way you exectly need)', function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://www.example.com');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'your headers');
next();
});
Also in the socket.io you do not need to specify separately headers for POST or GET... this is a different communication protocol.
Here is example for socket set you can try:
io.set( 'origins', '*www.example.com' );
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: Content-Type

axios delete call returns 405

We are running a Tornado service in the background which accepts post and delete calls from the React application.
Our axios.post call works perfectly fine but it fails on our delete request with the following error message
405 (Method Not Allowed)
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:3000' is therefore not allowed access.
export const StopBuild = (action$) =>
action$.ofType(STOPBUILD)
.mergeMap((action) => {
return Observable.fromPromise(axios.delete(action.stopRequest))
.map(response => PlatformBuildSuccess(response))
.catch(error => Observable.of(PlatformBuildFailure(error, action.platform)))
})
From server side, this is what we have currently set,
self.set_header("Content-Type", "*")
self.set_header("Access-Control-Allow-Origin", "*")
self.set_header("Access-Control-Allow-Headers", "*")
self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE')
Something else we noticed that when on the server side we only set the following header POST call still works. I think we are going wrong on the server end.
self.set_header("Access-Control-Allow-Origin", "*")
Any help would be appreciated.
What you can do is, allow cors in your API request:
Like this :
axios.delete(url, { crossdomain: true }) // an example
you can take this as an example and add crossdomain:true in your delete request.
let me know if cors error still persists.
This is a CORS issue. As the error states it, the DELETE operation is not allowed yet. Here is explained that you have to add the DELETE method to the Access-Control-Allow-Methods response header of the preflight request.
On server side, using nodejs, allowing CORS would look like this:
const corsMiddleware = (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', '*')
res.header('Access-Control-Allow-Methods', 'OPTIONS, POST, DELETE')
next()
}
app.use(corsMiddleware)
The request can be made from all origins with all headers, and OPTIONS, POST and DELETE methods are allowed.
For CORS request there is one package available called cors. You can try that by installing it as,
npm install cors --save
then you can require it and use that as middleware here the example,
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
More on cors npm package here

Nancy + .NET Core enable CORS not working

I have the following request on the clientside:
$.get(getUrl)
I have tried the following on the backend:
Is it possible to enable CORS using NancyFX?
I have also tried these four approaches (separately, hence commented out):
// protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
// {
// pipelines.AfterRequest += ctx =>
// {
// ctx.Response.Headers.Add("Access-Control-Allow-Origin", "*");
// ctx.Response.Headers.Add("Access-Control-Allow-Headers", "*");
// ctx.Response.Headers.Add("Access-Control-Allow-Methods", "*");
// };
// }
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
pipelines.AfterRequest += (ctx) =>
{
ctx.Response.Headers.Add("Access-Control-Allow-Origin", "*");
};
}
protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
{
base.RequestStartup(container, pipelines, context);
// pipelines.AfterRequest.AddItemToEndOfPipeline((ctx) =>
// {
// ctx.Response.WithHeader("Access-Control-Allow-Origin", "*")
// .WithHeader("Access-Control-Allow-Methods", "*")
// .WithHeader("Access-Control-Allow-Headers", "*");
// });
// pipelines.AfterRequest += (ctx) =>
// {
// ctx.Response.Headers.Add("Access-Control-Allow-Origin", "*");
// ctx.Response.Headers.Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// };
I have even tried for my module something like:
After += (Context) =>
{
Context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
Context.Response.Headers.Add("Access-Control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
Context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, x-requested-with, Authorization, Accept, Origin");
};
All yield the same:
XMLHttpRequest cannot load http://localhost:5000/registration/signup. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5001' is therefore not allowed access. The response had HTTP status code 401.
The 401 is because I am not passing in a custom header that is expected. I am just trying to work around the CORS issue first
Welp. This was a two headed snake. I had resorted to trying a basic nodejs reverse proxy, and when that didn't work... it all made sense.
It does not seem some of the approaches I took with Nancy could have ever worked, as I have auth middleware code, which is hit/run before the bootstrapper code. So preflight requests would always get a 401 instantly (they don't send custom headers the middleware was checking for) and the code that enables CORS would never get hit.
HOWEVER, the other issue is this is localhost. Browsers do not allow CORS for localhost apparently. So the solution here is to use ngrok (not tested for this, but no reason it shouldn't work). OR run chrome with disabled web security flag set to false (this approach varies depending on the OS).
I tried the latter option, and to solve my Nancy CORS code not being run, I removed it all and went with the standard .NET Core CORS approach outlined here: https://learn.microsoft.com/en-us/aspnet/core/security/cors
Now my Access-Control-Allow-Origin header is being set, and chrome is running somewhat unsecurely. But it works.
I think for production I will be using a reverse proxy like NGINX. And all of this will seem like a distant memory...

CORS Post Request Fails

I built an API with the SLIM Micro-Framework. I setup some middleware that adds the CORS headers using the following code.
class Cors{
public function __invoke(Request $request, Response $response, $next){
$response = $next($request, $response);
return $response
->withHeader('Access-Control-Allow-Origin', 'http://mysite')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
}
}
For my front-end, I used VueJS. I setup VueResource and created a function with the following code.
register (context, email, password) {
Vue.http({
url: 'api/auth/register',
method: 'POST',
data: {
email: email,
password: password
}
}).then(response => {
context.success = true
}, response => {
context.response = response.data
context.error = true
})
}
In chrome, the following error is logged to the console.
XMLHttpRequest cannot load http://mysite:9800/api/auth/register. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mysite' is therefore not allowed access.
Oddly enough, GET requests work perfectly.
You half 1/2 the solution here.
What you are missing is an OPTIONS route where these headers need to be added as well.
$app->options('/{routes:.+}', function ($request, $response, $args) {
return $response
->withHeader('Access-Control-Allow-Origin', 'http://mysite')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
});
This happens because preflight request is of OPTIONS type. You need to make an event listener on your request, which checks the type and sends a response with needed headers.
Unfortunately i don't know Slim framework, but here's the working example in Symfony.
First the headers example to be returned:
// Headers allowed to be returned.
const ALLOWED_HEADERS = ['Authorization', 'Origin', 'Content-Type', 'Content-Length', 'Accept'];
And in the request listener, there's a onKernelRequest method that watches all requests that are coming in:
/**
* #param GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event)
{
// Don't do anything if it's not the master request
if (!$event->isMasterRequest()) {
return;
}
// Catch all pre-request events
if ($event->getRequest()->isMethod('OPTIONS')) {
$router = $this->container->get('router');
$pathInfo = $event->getRequest()->getPathInfo();
$response = new Response();
$response->headers->set('Access-Control-Allow-Origin', $event->getRequest()->headers->get('Origin'));
$response->headers->set('Access-Control-Allow-Methods', $this->getAllowedMethods($router, $pathInfo));
$response->headers->set('Access-Control-Allow-Headers', implode(', ', self::ALLOWED_HEADERS));
$response->headers->set('Access-Control-Expose-Headers', implode(', ', self::ALLOWED_HEADERS));
$response->headers->set('Access-Control-Allow-Credentials', 'true');
$response->headers->set('Access-Control-Max-Age', 60 * 60 * 24);
$response->send();
}
}
Here i just reproduce the Origin (all domains are allowed to request the resource, you should probably change it to your domain).
Hope it will give some glues.
Actually CORS is implemented at browser level. and Even with
return $response
->withHeader('Access-Control-Allow-Origin', 'http://mysite')
->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
chrome and Mozilla will not set headers to allow cross origin. So, you need forcefully disable that..
Read more about disabling CORS
Disable same origin policy in Chrome
CORS can be hard to config. The key is that you need to set the special headers in your server and your client, and I don't see any Vue headers set, besides as far as I know http is not a function. However here is some setup for a post request.
const data = {
email: email,
password: password
}
const options = {
headers: {
'Access-Control-Expose-Headers': // all of your headers,
'Access-Control-Allow-Origin': '*'
}
}
Vue.http.post('api/auth/register', JSON.stringify(data), options).then(response => {
// success
}, response => {
// error
})
Notice that you need to stringify your data and you need to expose your headers, usually including the Access-Control-Allow-Origin header.
What I did in one of my own apps was to define interceptors so I don't worry to set headers for every request.
Vue.http.headers.common['Access-Control-Expose-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, x-session-token, timeout, Content-Length, location, *'
Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'

Categories

Resources