0

I am sending reactive form data through post request to java restful web api but it shows me CORS error While same is working fine in GET request. I already set the CORS header in response of rest api.

Angular Service Code :

 private headers = new Headers({ 'Content-Type': 'application/json'});
    baseURL='http://127.0.0.1:8080/userInformation/rest/UserService';
    addData(formdata: any){
        var body = JSON.stringify(formdata);
           return this.http.post(this.baseURL+'/adduser',body)
                            .subscribe(
                           res => {
                            console.log(res);
                         },
                      err => {
                        console.log('Error occured');
                      }
          );


  }

JAVA Rest API CODE :

       @POST
       @Produces(MediaType.APPLICATION_JSON)
       @Consumes(MediaType.APPLICATION_JSON)
       @Path("/adduser")
       public Response createUser(String val){  
           Gson gson = new Gson();
           User user = gson.fromJson(val, User.class);
           userDao.insertUser(user);
           String result="SUCCESS";
           return Response.ok().entity(result)
                    .header("Access-Control-Allow-Origin", "*")
                    .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD")
                    .build();
       }

Header Description : enter image description here I think when we are sending the data to rest api we need to set the CORS origin header to our angular code. How can I do this?

R. Richards
  • 24,603
  • 10
  • 64
  • 64
Nishant Varshney
  • 685
  • 2
  • 14
  • 34
  • This is exact error: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. – Nishant Varshney Jan 19 '18 at 23:24
  • Do you really mean [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) errors? I think you do. – R. Richards Jan 19 '18 at 23:25
  • Did you get `403` response status code? Also refer this post's answer https://stackoverflow.com/questions/46788969/angular2-spring-boot-allow-cross-origin-on-put/46789290#46789290 – hrdkisback Jan 20 '18 at 05:18
  • No I am getting error code 500. 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 500. – Nishant Varshney Jan 20 '18 at 09:27

3 Answers3

2

You can resolve it by using annotation on the Controller class declaration.

@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping({ "/controller" })
public class Controller {
}
pratik patel
  • 306
  • 5
  • 16
0

You can do this without changing the backend by running Angular with a proxy configuration. More details here.

In a nutshell:

  1. Change your baseUrl's port to 4200 (or whichever your Angular app runs on):

    baseURL = 'http://127.0.0.1:4200/userInformation/rest/UserService';
    
  2. Create a proxy.conf.json file in the root of your Angular project with the content:

    {
      "/userInformation": {
        "target": "http://127.0.0.1:8080",
        "secure": false
      }
    }
    
  3. Run the Angular app with ng serve --proxy-config proxy.conf.json

At this point your app runs on port 4200 and when you try to hit an endpoint containing /userInformation, it hijacks the URL and sends it to the target you set in your proxy configuration plus the rest of the path, so http://127.0.0.1:8080/userInformation/rest/UserService/addUser. By the way, if your endpoint is not up in your backend, the browser dev console will complain about that endpoint on port 4200, but the call really went to 8080.

Voicu
  • 16,921
  • 10
  • 60
  • 69
0

We need to add filter for incoming request as below:

Create a filter CrossOrigin as below :

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;

public class CrossOrigin implements ContainerResponseFilter {

     @Override
        public ContainerResponse filter(ContainerRequest creq, ContainerResponse cresp) {

            cresp.getHttpHeaders().putSingle("Access-Control-Allow-Origin", "*");
            cresp.getHttpHeaders().putSingle("Access-Control-Allow-Credentials", "true");
            cresp.getHttpHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD");
            cresp.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");

            return cresp;
        }
}

And then register it in web.xml :

    <servlet>
        <servlet-name>Jersey RESTful Application</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
          <param-name>jersey.config.server.provider.packages</param-name>
          <param-value>com.newgen.ap2</param-value>
        </init-param>
        <init-param>
        <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
        <param-value>com.newgen.ap2.CrossOrigin</param-value>
     </init-param>

  </servlet>
Nishant Varshney
  • 685
  • 2
  • 14
  • 34