简体   繁体   中英

Reason: CORS header ‘Access-Control-Allow-Origin’ missing even though explictly specificed in java resource

I am testing my backend (Java using Jersey on tomcat server) and frontend (Angular 4 using webpack to serve) on two different ports, thus I am getting a cors access control origin block. For my get methods everything works fine and any data requested is found on the UI. Now I am testing my POST method and I keep getting the same message in the title.

My post method should persist the data sent to it and return a response with the location of the new persisted entity.

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response persistAccountLocation(AccountLocation entity) throws URISyntaxException {


    accountLocationService.persist(entity);

    JsonObject object = Json.createObjectBuilder()
            .add("location", "api/v1/accounts_locations/"+entity.getLocation_id()).build();

    return Response.status(Response.Status.CREATED)// 201
            .entity("Location created")
            .header("Access-Control-Allow-Origin","*")
            .header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE")
            .allow("OPTIONS")
            .entity(object.toString()).build();
}

In my network tab in firefox browser I only see OPTIONS with 200 status

Host: localhost:8081
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: access-control-allow-origin,content-type
Origin: http://localhost:4200
Connection: keep-alive

but after that the post is never happens. I am assuming CORS blocks it at that point. Is there somewhere else I should be allowing access control besides the resource class? I have read that typical all CORS configuration is done on server side. Totally lost. Any feedback appreciated

EDIT

public class CORSResponseFilter
implements ContainerResponseFilter {

    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-Methods", "GET, POST, DELETE, PUT, OPTIONS");         
        headers.add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type,");
    }

}

I have made aa filter with slight adjustments and registered it to my app

public class JaxRsApplication extends ResourceConfig{
    public JaxRsApplication() {

        //  register application resources - unmapped resources will throw exception
        register(AccountLocationResource.class);

        register(CORSResponseFilter.class);
    }

Quite a good answer is provided in How to handle CORS using JAX-RS with Jersey stackoverflow question.

You have given a link to Jersey 1, but please make sure what version you are using.

This way you will not have to write

        .header("Access-Control-Allow-Origin","*")
        .header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE")
        .allow("OPTIONS")

for every request. Filter will apply the options for you.

One more thing I have noticed

return Response.status(Response.Status.CREATED)// 201
        .entity("Location created") // <- entity() call here
        .header("Access-Control-Allow-Origin","*")
        .header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE")
        .allow("OPTIONS")
        .entity(object.toString()).build(); // <- one more entity() call here (not sure what effect it may have)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM