Calling REST resources using Ajax is not working fine
I am trying to call a service sides on my localhost:8080/person (POST) through VueJS app on my localhost:8084 but it is not working. I tried to enable CORS config. in application.properties with the below :
quarkus.http.cors=true
quarkus.http.cors.origins=http://localhost:8084
quarkus.http.cors.headers=accept, authorization, content-type, x-requested-with
quarkus.http.cors.methods=GET, PUT, POST
Expected behavior
It should work fine and be able to call my resource.
Actual behavior
Browser logs error :
Access to XMLHttpRequest at 'http://localhost:8080/person' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Even it is not reaching to my ContainerRequestFilter code.
To Reproduce
Steps to reproduce the behavior:
Configuration
> quarkus.http.cors=true
> quarkus.http.cors.origins=http://localhost:8084
> quarkus.http.cors.headers=accept, authorization, content-type, x-requested-with
> quarkus.http.cors.methods=GET, PUT, POST
Environment (please complete the following information):
uname -a or ver: Darwin SDG0268LMAC 18.6.0 Darwin Kernel Version 18.6.0: Thu Apr 25 23:16:27 PDT 2019; root:xnu-4903.261.4~2/RELEASE_X86_64 x86_64java -version: OpenJDK Runtime Environment Corretto-8.202.08.2 (build 1.8.0_202-b08)Additional context
Event if CORS is disabled same issue is produced.
Do you have to go the cors route? I'd just configure npm (vuejs) to proxy anything on localhost:8084/person to localhost:8080/person. In production on kubernetes this sort of thing is better done with an 2 ingresses sharing same dns.
Edit: if you staying with cors, try using your real ip, I've had trouble with localhost in the past
I took a look and it seems this is caused by the way how the CORS servlet filter and the RESTEasy servlet filter interact. I'll continue digging on Monday.
That makes sense now. Because request is not being reached to quarkus request filter so it must be stopped by some earlier stage. Thanks for the update.
Found two more strange scenarious:
@Provider
public class CORSFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
MultivaluedMap<String, Object> headers = responseContext.getHeaders();
headers.putSingle("Access-Control-Allow-Origin", "*");
...
headers.putSingle("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
}
}
headers.putSingle("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE, PATCH, HEAD");
For some reason PATCH requests are not catched by ContainerResponseFilter at all.
Ad 1., that's because the CORS servlet filter expects to find the value of the Origin header in the set of configured allowed origins. Supporting * is probably a good idea.
Ad 2., that's probably also because the CORSFilter and ResteasyFilter interact in a weird way. I didn't have time to look into it yet, but I should get to it this week.
Ad 1. again: the CORS filter already allows all origins, if quarkus.http.cors.origins is not set. Not sure if adding support for * is worth it.
Is this still a WIP? Just doing a check-in to see if there is something in motion (npm dev UI environment with quarkus dev backend environment). The scenario I have is a quarkus w/ undertow, resteasy, and smallrye-openapi and using Postman not getting any of the CORS-associated headers in the response for the rest/openapi endpoint (no Access-Control-Allow-Origin header entry).
Tested quarkus 0.20.0 and 0.23.1
quarkus.smallrye-openapi.path=/openapi
quarkus.http.cors=true
#testing with and without, no difference
#quarkus.http.cors.origins=http://localhost:3000,http://localhost:8080
#testing with and without, no difference
#quarkus.http.cors.exposed-headers=Access-Control-Allow-Origin
I have tried the last version 0.23.1 but it doesn't work: Back-end still rejects requests from a different domain, respectively my react Front-end app still receive
Access to XMLHttpRequest at 'http://localhost:8080/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Is this issue still not fixed? Is there is any suitable alternative?
I'm testing CORS using http://www.test-cors.org on Quarkus 0.23.2 and also the latest master branch, with this config file:
quarkus.http.cors=true
quarkus.http.cors.origins=http://www.test-cors.org
quarkus.http.cors.headers=accept,authorization,content-type,x-requested-with,x-foobar
quarkus.http.cors.methods=GET,POST,PUT
It seems to work just fine.
Just tested 0.23.2, hopefully I'm the minor but still not getting the Access-Control-Allow-Origin headers (tested both mvn quarkus:dev and a production build running the java -jar *-runner.jar).
application.properties
quarkus.smallrye-openapi.path=/openapi
quarkus.http.cors=true
#testing with and without, no difference
#quarkus.http.cors.origins=http://localhost:3000,http://localhost:8080
#tried this related to potential issue with localhost, no difference
#quarkus.http.cors.origins=http://127.0.0.1:3000
#testing with and without, no difference
#quarkus.http.cors.exposed-headers=Access-Control-Allow-Origin
#testing with and without, no difference
#quarkus.http.cors.headers=accept, origin, authorization, content-type, x-requested-with
#testing with and without, no difference
#quarkus.http.cors.methods=GET,PUT,POST,OPTIONS
@dhartford Can you please provide more details? For example, do you have a reproducer using curl (or HTTPie)?
Also, do you perhaps use some kind of a caching proxy or something similar? I've noticed that the Quarkus CORS handler should at the very least include Vary: Origin (and perhaps other values for the Vary header), but that didn't prevent it from working in the basic local usecase.
Using postman and curl for direct functional testing, and 'npm start' with a webapp with a fetch for applied testing (which states the no Access-Control-Allowed-Origin header problem), all localhost or 127.0.0.1 without any caching proxy.
curl -v http://localhost:8080/openapi/app
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /openapi/app HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< **Content-Type: application/json**
< **Content-Length: 40**
<
* Connection #0 to host localhost left intact
{ "APP_NAME": "Changed App Name Here so length may be different"}
Ah, so it's on the OpenAPI endpoint, I didn't try that. I'll check tomorrow, thanks for the info.
Dears,
I've generated the issue again with latest version. I've created two repositories for this. One for Quarkus as the backend APIs and the other one is the VueJS as front end.
Quarkus : https://github.com/iabughosh/microprofile-health
VueJS : https://github.com/iabughosh/VueJs
I will do some debugging from my end too.
Regards.
The same issue is still produced as @dhartford describe, even with the latest version 0.23.2
Hopefully, it will be fixed in the next release!
I have the same issue as well. When I use
quarkus.http.cors.origins=http://localhost:8081
is working fine. But when using *
quarkus.http.cors.origins="*"`
is not working no matter what I do.
Instead of *, just leave the quarkus.http.cors.origins property out.
One other thing I'd like to highlight, because I've seen it in the reports here (I already mentioned this in the other CORS issue): if the request doesn't have the Origin header, the response won't have CORS headers either.
This is perfectly fine per my understanding of CORS. (What's worse is that this doesn't necessarily play well with caching proxy servers. My understanding is that we should at least always include Vary: Origin if CORS is enabled. But that shouldn't be a problem in the investigations here.)
@Ladicek you are right. It is working now only with:
quarkus.http.cors=true
Dears,
Is still this considered as a bug ? because for me even if I disabled cors config, I am still facing the same issue !
Does anyone here have a reproducer with a ReactJS application accessing a Quarkus REST API to demonstrate this error to maintainers?
@iabughosh I think, this issue should be marked as solved.
for me now it's working correctly.
with the configuration as @Ladicek mentioned before.
quarkus.http.cors=true
quarkus.http.cors.origins=http://localhost:3000
quarkus.http.cors.headers=accept,origin,authorization,content-type,x-requested-with,x-foobar
quarkus.http.cors.methods=GET,POST,PUT,OPTIONS
Unfortunately, the main problem - which is disabling the cors still not working fine. I will try these configuration and report back.
Just Tried @Ladicek and it is working fine (which is great :) ); however, it is not working if I disabled CORS. I will close this bug as the main issue is resolved for me.
As I said, the only way to make it work on any domain is using only one single CORS property:
quarkus.http.cors=true
If I disable it, the problem still persists. I'm using Quarkus 0.25.0.
IMHO quarkus.http.cors.origins=* should also work, but for now, it isn't.
Currently, you can achieve "all origins" by simply omitting quarkus.http.cors.origins altogether. I wonder what should be the difference between "no quarkus.http.cors.origins at all" and "quarkus.http.cors.origins=*".
@Ladicek For the quarkus.http.cors.origins=* discussion item, I can at least share my experience which may not be related to the catalyst, but may support it. When working in certain regulatory fields, you often have to explicitly list all (security) relevant configuration values, often copying the default value, to show reviewers/auditors the intent as explicitly as possible.
HTH!
@dhartford In that case, it should be possible to just write quarkus.http.cors.origins=, but I'd expect that in highly regulated fields, allowing all origins wouldn't be what you want :-) Thanks for an interesting case though!
I have same issue..i have tried all above ways.but still not work.issue is still there of cors
Most helpful comment
Dears,
I've generated the issue again with latest version. I've created two repositories for this. One for Quarkus as the backend APIs and the other one is the VueJS as front end.
Quarkus : https://github.com/iabughosh/microprofile-health
VueJS : https://github.com/iabughosh/VueJs
I will do some debugging from my end too.
Regards.