2

I am writing a web application where the client posts (JSON) form data to the and the server should also respond with a JSON. The server-side is written using java servlets, running on Tomcat and the client is written in Angular 7. Unfortunately, I am facing a CORS error even after enabling cors via the HTTP headers. Is there anything I am missing?

This is the error I get on the client side: Access to XMLHttpRequest at 'http://localhost:8080/mysocial/signIn' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I have read the following posts and tried each of the solutions but the problem still persists: CORS enabled but still getting CORS error

How to fix CORS issue http request in Angular 5

As I have said I have enabled the CORS headers. The code snippets show my server side and client side code:

// From my data service (client-side angular 7)
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private baseUrl: string = "http://localhost:8080/mysocial";
  private http: HttpClient;

  constructor(http: HttpClient) { 
    this.http = http;
  }

  public authenticateLogin(username: string, password: string) //: boolean
  {
    let url: string = `${this.baseUrl}/signIn`;
    let header = new HttpHeaders({'Accept': 'application/json' ,'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
    let httpOptions = { headers: header };
    let body = {username: username, password: password};

    return this.http.post(url, body, httpOptions).subscribe(
      (response) => console.log(response),
      (err) => console.log(err)
    );
    //return true;
  }
}

Server-side code:

// server-side java servlets code
   private void configResponse(HttpServletResponse response)
   {
      response.setContentType("application/json");
      response.addHeader("Access-Control-Allow-Origin", "http://localhost:4200");
      response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD");
   }

   public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
   {
      Model model = (Model) getServletContext().getAttribute("model");
      String username = request.getParameter("username");
      String password = request.getParameter("password");

      configResponse(response);
      PrintWriter out = response.getWriter();

      if (model.validateLoginDetails(username, password))
      {
         String firstName = model.getUserInfo("firstName", "username", username);
         int id = Integer.parseInt(model.getUserInfo("id", "username", username));

         HttpSession session = request.getSession();
         session.setMaxInactiveInterval(60);
         session.setAttribute("username", username);
         session.setAttribute("firstname", firstName);
         session.setAttribute("id", id);

         JsonObject value = createJsonResponse(username, password, true);
         out.println(value);
      }
      else
      {
         JsonObject value = createJsonResponse(username, password, false);
         out.println(value);
      }
   }

I expect the server to send a JSON back to the client but I'm getting a CORS error from the client.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
David
  • 361
  • 1
  • 3
  • 15
  • Your server code seems to only be adding the Access-Control-Allow-\* response headers for POST responses. The code needs to also add the Access-Control-Allow-Origin and Access-Control-Allow-Methods headers for responses to OPTIONS requests — and for OPTIONS responses, the server also needs to send back an ‘Access-Control-Allow-Headers: Content-Type’. All that is necessary in order to handle the CORS preflight OPTIONS request. – sideshowbarker Jul 05 '19 at 00:53
  • Drop the part of your server code that’s adding the Access-Control-Allow-Methods header for POST responses — that header is only necessary for OPTIONS responses. And in your frontend JavaScript code, drop the 'Access-Control-Allow-Origin': '*' part; the Access-Control-Allow-Origin header is not a request header — instead it’s only a response header, for servers to send. – sideshowbarker Jul 05 '19 at 00:54
  • 1
    Instead of trying to write your own custom CORS handling on the server side, you probably want to consider using the CORS handling that’s already built into Tomcat. See https://enable-cors.org/server_tomcat.html and http://tomcat.apache.org/tomcat-9.0-doc/config/filter.html#CORS_Filter and https://stackoverflow.com/questions/tagged/cors+tomcat – sideshowbarker Jul 05 '19 at 00:58
  • I've added the tomcat CORS filter but still getting the same error. Could it be something else in the code? – David Jul 05 '19 at 01:07
  • I don’t know. I guess it could be that some other part of the server code is catching and handling the OPTIONS request before the filter gets evaluated. If you look through some of the https://stackoverflow.com/questions/tagged/cors+tomcat questions and answers, you might find a question that describes a similar problem. – sideshowbarker Jul 05 '19 at 01:17
  • I noticed something weird just recently. Get requests work perfectly and reach the server. A response is even sent back to the client. However, post requests always fail. Is there something specific about post requests and CORS that I am missing? – David Jul 05 '19 at 15:14

1 Answers1

1

Just for completeness and for anyone who may come across this problem, I was able to solve this problem using the tomcat filters provided here: http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter (shown by sideshowbarker (https://stackoverflow.com/users/441757/sideshowbarker))

There had to change some server configurations first to match the filter. I'd suggest customizing the filter to your needs.

David
  • 361
  • 1
  • 3
  • 15